各种排序算法总结

转载:http://blog.csdn.net/warringah1/article/details/8951220

明天就要去参加阿里巴巴的实习生笔试了,虽然没想着能进去,但是态度还是要端正的,也没什么可以准备的,复习复习排序吧。

1 插入排序

void InsertSort(int a[], int n)

{

      for (int i=1; i<n; ++i) {

            int key = a[i];

            int j = i - 1;

            while(j>=0 && a[j]>key) {

                  a[j+1] = a[j];

                  --j;

            }

            a[j+1] = key;

      }

}

插入排序是稳定的排序,平均和最坏时间复杂度是O(n^2)。最好的时间复杂度是O(n),对应于全部排好序的情况。

 

2 冒泡排序

void BubbleSort(int a[], int n)

{

      for (int i=1; i<n; ++i) {

            for(int j=0; j<n-i; ++j) {

                  if(a[j]>a[j+1]) {

                       inttemp = a[j];

                       a[j] = a[j+1];

                       a[j+1] = temp;

                  }

            }

      }

}

冒泡排序是稳定的排序,平均和最坏时间复杂度是O(n^2)。

 

3 选择排序

每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。选择排序是不稳定的排序方法。

void SelectSort(int a[], int n)

{

      for (int i=0; i<n-1; ++i) {

            for(int j=i+1; j<n; ++j) {

                  if(a[i]>a[j]) {

                       inttemp = a[i];

                       a[i] = a[j];

                       a[j] = temp;

                  }

            }

      }

}

选择排序是不稳定的,因为,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了平均和最坏时间复杂度是O(n^2)。

 

4 希尔排序(缩小增量排序)

该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。

void ShellSort(int a[], int n)

{

      for (int gap=n/2; gap>0; gap/=2) {

            for(int i=0; i<gap; ++i) {

                  for(int j=i+gapj<nj+=gap) {

                       if(a[j]<a[j-gap]) {

                             int temp = a[j];

                             int k = j-gap;

                             while (k>=0&&a[k]>temp) {

                                   a[k+gap] = a[k];

                                   k -= gap;

                             }

                             a[k+gap] = temp;

                       }

                  }

            }

      }

}

 

void ShellSortImproved(int a[], int n)

{

      for (int gap=n/2; gap>0; gap/=2) {

            for(int j=gapj<n; ++j) {

                  if(a[j]<a[j-gap]) {

                       inttemp = a[j];

                       intk = j - gap;

                       while(k>=0 && a[k]>temp) {

                             a[k+gap] = a[k];

                             k -= gap;

                       }

                       a[k+gap] = temp;

                  }

            }

      }

}

希尔排序是不稳定的。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。使用希尔增量时,最坏运行时间是O(n^2),使用Hibbard增量时,最坏运行时间是O(n^3/2)。

 

5. 堆排序

void MaxHeapify1(int a[], int nint i)

{

      int l = LEFT(i);

      int r = RIGHT(i);

      int largest;

      if (l<n&& a[l]>a[i])

            largestl;

      else

            largesti;

      if (r<n&& a[r]>a[largest])

            largestr;

      if (largest!=i) {

            swap(a[i], a[largest]);

            MaxHeapify1(anlargest);

      } else

            return;

}

 

void MaxHeapify2(int a[], int nint i)

{

      int c,  largest;

      while (1){

            cLEFT(i);

            if (c>=n)

                  break;

            if (a[i]<a[c])

                  largestc;

            else

                  largesti;

            if (c+1<n) {

                  if(a[largest]<a[c+1])

                       largestc + 1;

            }

            if (largest!=i) {

                  swap(a[i], a[largest]);

                  ilargest;

            } else

                  break;

      }

}

 

void HeapSort(int a[], int n)

{

      for (int i=n/2-1; i>=0;--i)

            MaxHeapify1(ani);

      for (int i=n-1; i>0; --i) {

            swap(a[i], a[0]);

            MaxHeapify1(ai, 0);

      }

}

堆排序是原地排序,但是不是稳定排序。时间复杂度O(nlogn)。

 

6 归并排序

void Merge(int a[], int pint qint r)

{

      int n1 = q - p + 1;

      int n2 = r - (q+1) +1;

 

      int *L = new int[n1+1];

      int *R = new int[n2+1];

 

      for (int i=0; i<n1; ++i)

            L[i] = a[p+i];

      for (int i=0; i<n2; ++i)

            R[i] = a[q+1+i];

      L[n1] = INT_MAX;//哨兵

      R[n2] = INT_MAX;

      int i = 0, j = 0;

      for (int k=pk<=r; ++k) {

            if (L[i]<=R[j])

                  a[k] = L[i++];

            else

                  a[k] = R[j++];

      }

      delete[] L;

      delete[] R;

}

 

void MergeSort(int a[], int pint r)

{

      if (p<r) {;

            int q = ((r-p)>>1) + p;

            MergeSort(apq);

            MergeSort(aq+1, r);

            Merge(apqr);

      }

}

合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。时间复杂度是O(nlogn)。可以在空间复杂度O(1)的条件下实现归并排序

 

7. 快速排序

被快速排序所使用的空间,依照使用的版本而定。使用原地(in-place)分区的快速排序版本,在任何递归调用前,仅会使用固定的额外空间。然而,如果需要产生O(log n)嵌套递归调用,它需要在他们每一个存储一个固定数量的信息。因为最好的情况最多需要O(log n)次的嵌套递归调用,所以它需要O(log n)的空间。最坏情况下需要O(n)次嵌套递归调用,因此需要O(n)的空间。

void Median3(int a[], int pint r)

{

      int median = p + ((r-p)>>1);

      if (a[p]>a[median])

            swap(a[p], a[median]);

      if (a[p]>a[r])

            swap(a[p], a[r]);

      if (a[median]>a[r])

            swap(a[median], a[r]);

      swap(a[median], a[r]);

}

 

int Partition1(int a[], int pint r)

{

      Median3(apr);

      int x = a[r];

      int i = p - 1;

      for (int j=pj<=r-1; ++j) {

            if (a[j]<=x) {

                  ++i;

                  swap(a[i], a[j]);

            }

      }

      swap(a[i+1], a[r]);

      return i+1;

}

 

int Partition2(int a[], int pint r)

{

      Median3(apr);

      int i = p-1, j = r;

      int x = a[r];

      for (;;) {

            while(a[++i]<x);

            while(a[--j]>x);

            if (i<j)

                  swap(a[i], a[j]);

            else

                  break

      }

      swap(a[i], a[r]);

      return i;

}

 

void QuickSort(int a[], int pint r) {

      if (p<r) {

            int q = Partition2(apr);

            QuickSort(apq-1);

            QuickSort(aq+1, r);

      }

}

快速排序是不稳定的排序,最差时间复杂度是O(n^2),平均时间复杂度是O(nlogn)。

 

8. 桶排序

void BucketSort(int a[], int n)

{

      int *count = new int[1000];

      memset(count, 0, sizeof(int)*1000);

      for (int i=0; i<n; ++i) {

            ++count[a[i]];

      }

      int k = 0;

      for (int i=0; i<1000; ++i){

            while(count[i]--){

                  a[k++] = i;

            }

      }

}

如果count有M个单元,算法用时O(M+N),桶排序是稳定的排序。但是需要额外的空间。

 

 

稳定的排序有:冒泡,插入,归并,基数,桶。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259385.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CentOS7 上安装 Zookeeper-3.4.9 服务

在 CentOS7 上安装 zookeeper-3.4.9 服务1、创建 /usr/local/services/zookeeper 文件夹&#xff1a; mkdir -p /usr/local/services/zookeeper 2、进入到 /usr/local/services/zookeeper 目录中&#xff1a; cd /usr/local/services/zookeeper 3、下载 zookeeper-3.4.9.…

c语言在程序中显示现在星期几,C语言程序设计: 输入年月日 然后输出是星期几...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include main(){int year,month,day0,a,b,week,c,i,sum0,days,d;printf("please input year,month,days\n");scanf("%d,%d,%d",&year,&month,&days);for(i1;i{if (year%40){if(year%1000){if (ye…

static之用法

本文转载于http://www.cnblogs.com/stoneJin/archive/2011/09/21/2183313.html 在C语言中&#xff0c;static的字面意思很容易把我们导入歧途&#xff0c;其实它的作用有三条。 &#xff08;1&#xff09;先来介绍它的第一条也是最重要的一条&#xff1a;隐藏。 当我们同时编译…

HTTP响应报文与工作原理详解

HTTP 是一种请求/响应式的协议&#xff0c;即一个客户端与服务器建立连接后&#xff0c;向服务器发送一个请求;服务器接到请求后&#xff0c;给予相应的响应信息。 超文本传输协议(Hypertext Transfer Protocol&#xff0c;简称HTTP)是应用层协议。HTTP 是一种请求/响应式的协议…

优先队列priority_queue 用法详解

转载&#xff1a; 1.优先队列priority_queue 用法详解 2.STL系列之五 priority_queue 优先级队列 优先队列是队列的一种&#xff0c;不过它可以按照自定义的一种方式&#xff08;数据的优先级&#xff09;来对队列中的数据进行动态的排序 每次的push和pop操作&#xff0c;队…

android自定义画板,android 自定义控件 -- 画板

如图&#xff1a;package com.example.myview;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Paint.Style;import android.util.Attrib…

postgreSQl pathman 用法语句总结

2019独角兽企业重金招聘Python工程师标准>>> --新建主表 create table part_test(id int, info text, crt_time timestamp not null); --插入测试数据 insert into part_test select id,md5(random()::text),clock_timestamp() (id|| hour)::interval from generat…

Oracle查询笔记

-- tanslate(str,from_str,to_str) -- 将str中的from_str替换成to_str select translate(hello,e,o) t from dual;-- instr(str,des_str) -- 可以实现like功能 select instr(hello,g),instr(hello,h),instr(hello,l) from dual; -- decode(value,s1,r1,s2,r2,default) -- 类似于…

全排列算法及实现

转载&#xff1a; 1.http://blog.csdn.net/hackbuteer1/article/details/6657435 2.http://blog.sina.com.cn/s/blog_9f7ea4390101101u.html 3.http://www.slyar.com/blog/stl_next_permutation.html 4.http://www.cplusplus.com/reference/algorithm/next_permutation/ 5…

ssh配置文件详解

配置“/etc/ssh/sshd_config”文件 “/etc/ssh/sshd_config”是OpenSSH的配置文件&#xff0c;允许设置选项改变这个daemon的运行。这个文件的每一行包含“关键词&#xff0d;值”的匹配&#xff0c;其中“关键词”是忽略大小写的。下面列出来的是最重要的关键词&#xff0…

EC+VO+SCOPE for ES3

词法环境 词法作用域 词法作用域&#xff08;lexcical scope&#xff09;。即JavaScript变量的作用域是在定义时决定而不是执行时决定&#xff0c;也就是说词法作用域取决于源码。 词法环境 用于定义特定变量和函数标识符在ECMAScript代码的词法嵌套结构上的关联关系&#xff0…

你真的会写二分检索吗?

转载&#xff1a;http://blog.chinaunix.net/uid-1844931-id-3337784.html 前几天在论坛上看到有统计说有80%的程序员不能够写对简单的二分法。二分法不是很简单的吗&#xff1f; 这难道不是耸人听闻&#xff1f; 其实&#xff0c;二分法真的不那么简单&#xff0c;尤其是二…

android listview动态加载网络图片不显示,Android Listview异步动态加载网络图片

Android Listview异步动态加载网络图片详见&#xff1a; http://blog.sina.com.cn/s/blog_62186b460100zsvb.html标签&#xff1a; Android SDK代码片段(5)[代码] (1)定义类MapListImageAndText管理ListViewItem中控件的内容01 package com.google.zxing.client.android.AsyncL…

C#-面向对象的多态思想 ---ShinePans

总结: 多态是面向对象的核心.---------能够理解为一个方法,多种实现, 在这里能够用虚方法,抽象类,接口能够实现多态 1.首先利用接口来实现多态: 接口相当于"功能,"接口能够实现多继承,分为 显式实现接口和隐式实现接口 keyword为interface格式: interface 接口名 { …

wxpy 0.1.2微信机器人 / 优雅的微信个人号API

微信机器人 / 优雅的微信个人号API&#xff0c;基于 itchat&#xff0c;全面优化接口&#xff0c;更有 Python 范儿。用来干啥一些常见的场景控制路由器、智能家居等具有开放接口的玩意儿跑脚本时自动把日志发送到你的微信加群主为好友&#xff0c;自动拉进群中跨号或跨群转发消…

c++中try catch的用法

在c中&#xff0c;可以直接抛出异常之后自己进行捕捉处理&#xff0c;如&#xff1a;&#xff08;这样就可以在任何自己得到不想要的结果的时候进行中断&#xff0c;比如在进行数据库事务操作的时候&#xff0c;如果某一个语句返回SQL_ERROR则直接抛出异常&#xff0c;在catch块…

const in c and cpp

http://c-faq.com/ansi/constasconst.html 转载于:https://www.cnblogs.com/invisible/p/3333575.html

android ndk调用出错,由于Android-NDK应用程序的权限问题,为什么fopen在本地方法中失败?...

errno 0;FILE *fp;fp fopen("jigar.txt","wb");if(fp NULL)__android_log_print(ANDROID_LOG_ERROR, APPNAME, "FOPEN FAIL with %d",errno);else__android_log_print(ANDROID_LOG_ERROR, APPNAME, "FOPEN pass ");它得到失败&…

循环队列

什么是队列&#xff1f; 队列(Queue)也是一种运算受限的线性表。它仅仅同意在表的一端进行插入&#xff0c;而在还有一端进行删除。同意删除的一端称为队头(front)&#xff0c;同意插入的一端称为队尾(rear)。 FIFO原则 队列具有先进先出原则&#xff0c;与栈的先进后出形成对照…

T(n) = 25T(n/5)+n^2的时间复杂度 计算方法

对于T(n) a*T(n/b)c*n^k;T(1) c 这样的递归关系&#xff0c;有这样的结论&#xff1a; if (a > b^k) T(n) O(n^(logb(a)));logb(a)b为底a的对数 if (a b^k) T(n) O(n^k*logn); if (a < b^k) T(n) O(n^k); a25; b 5 ; k2 ab^k 故T(n)O(n^k*logn)O(n^2*logn)…