C++排序有哪几种最常用,最好用?

作者&投稿:曹京 (若有异议请与网页底部的电邮联系)
C++排序有哪几种最常用,最好用?~

(1)“冒泡法”

冒泡法大家都较熟悉。其原理为从a[0]开始,依次将其和后面的元素比较,若a[0]>a[i],则交换它们,一直比较到a[n]。同理对a[1],a[2],...a[n-1]处理,即完成排序。下面列出其代码:

void bubble(int *a,int n) /*定义两个参数:数组首地址与数组大小*/

{

int i,j,temp;

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

for(j=i+1;j<n;j++) /*注意循环的上下限*/

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

temp=a[i];

a[i]=a[j];

a[j]=temp;

}

}

冒泡法原理简单,但其缺点是交换次数多,效率低。

下面介绍一种源自冒泡法但更有效率的方法“选择法”。



(2)“选择法”

选择法循环过程与冒泡法一致,它还定义了记号k=i,然后依次把a[k]同后面元素比较,若a[k]>a[j],则使k=j.后看看k=i是否还成立,不成立则交换a[k],a[i],这样就比冒泡法省下许多无用的交换,提有了效率。

void choise(int *a,int n)

{

int i,j,k,temp;

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

k=i; /*给记号赋值*/

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

if(a[k]>a[j]) k=j; /*是k总是指向小元素*/

if(i!=k) { /*当k!=i是才交换,否则a[i]即为小*/

temp=a[i];

a[i]=a[k];

a[k]=temp;

}

}

}

选择法比冒泡法效率更有,但说到有效率,非“快速法”莫属,现在就让我们来了解它。



(3)“快速法”

快速法定义了三个参数,(数组首地址*a,要排序数组起始元素下标i,要排序数组结束元素下标j). 它首先选一个数组元素(一般为a[(i+j)/2],即中间元素)作为参照,把比它小的元素放到它的左边,比它大的放在右边。然后运用递归,在将它左,右两个子数组排序,后完成整个数组的排序。下面分析其代码:

void quick(int *a,int i,int j)

{

int m,n,temp;

int k;

m=i;

n=j;

k=a[(i+j)/2]; /*选取的参照*/

do {

while(a[m]<k&&m<j) m++; /* 从左到右找比k大的元素*/

while(a[n]>k&&n>i) n--; /* 从右到左找比k小的元素*/

if(m<=n) { /*若找到且满足条件,则交换*/

temp=a[m];

a[m]=a[n];

a[n]=temp;

m++;

n--;

}

}while(m<=n);

if(m<j) quick(a,m,j); /*运用递归*/

if(n>i) quick(a,i,n);

}

(4)“插入法”

插入法是一种比较直观的排序方法。它首先把数组头两个元素排好序,再依次把后面的元素插入适当的位置。把数组元素插完也就完成了排序。

void insert(int *a,int n)

{

int i,j,temp;

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

temp=a[i]; /*temp为要插入的元素*/

j=i-1;

while(j>=0&&temp<a[j]) { /*从a[i-1]开始找比a[i]小的数,同时把数组元素向后移*/

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

j--;

}

a[j+1]=temp; /*插入*/

}

}

(5)“shell法”

shell法是一个叫 shell 的美国人与1969年发明的。它首先把相距k(k>=1)的那几个元素排好序,再缩小k值(一般取其一半),再排序,直到k=1时完成排序。下面让我们来分析其代码:

void shell(int *a,int n)

{

int i,j,k,x;

k=n/2; /*间距值*/

while(k>=1) {

for(i=k;i<n;i++) {

x=a[i];

j=i-k;

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

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

j-=k;

}

a[j+k]=x;

}

k/=2; /*缩小间距值*/

}

}

上面我们已经对几种排序法作了介绍,现在让我们写个主函数检验一下。



#include



/*别偷懒,下面的"..."代表函数体,自己加上去哦!*/

void bubble(int *a,int n)

{

...

}

void choise(int *a,int n)

{

...

}

void quick(int *a,int i,int j)

{

...

}

void insert(int *a,int n)

{

...

}

void shell(int *a,int n)

{

...

}



/*为了打印方便,我们写一个print吧。*/[code]

void print(int *a,int n)

{

int i;

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

printf("%5d",a[i]);

printf("
");

}



main()

{ /*为了公平,我们给每个函数定义一个相同数组*/

int a1[]={13,0,5,8,1,7,21,50,9,2};

int a2[]={13,0,5,8,1,7,21,50,9,2};

int a3[]={13,0,5,8,1,7,21,50,9,2};

int a4[]={13,0,5,8,1,7,21,50,9,2};

int a5[]={13,0,5,8,1,7,21,50,9,2};



printf("the original list:");

print(a1,10);

printf("according to bubble:");

bubble(a1,10);

print(a1,10);

printf("according to choise:");

choise(a2,10);

print(a2,10);

printf("according to quick:");

quick(a3,0,9);

print(a3,10);

printf("according to insert:");

insert(a4,10);

print(a4,10);

printf("according to shell:");

shell(a5,10);

print(a5,10);

}

测试方法:每个比较操作、交换操作下面各加一个计数器就可以了,最后输出。

一、冒泡排序
  已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先比较a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变。再比较a[2]与a[3]的值,若a[2]大于a[3]则交换两者的值,否则不变。再比较a[3]与a[4],以此类推,最后比较a[n-1]与a[n]的值。这样处理一轮后,a[n]的值一定是这组数据中最大的。再对a[1]~a[n-1]以相同方法处理一轮,则a[n-1]的值一定是a[1]~a[n-1]中最大的。再对a[1]~a[n-2]以相同方法处理一轮,以此类推。共处理n-1轮后a[1]、a[2]、……a[n]就以升序排列了。
  优点:稳定,比较次数已知;
  缺点:慢,每次只能移动相邻两个数据,移动数据的次数多。
  
二、选择排序
  已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先比较a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变。再比较a[1]与a[3]的值,若a[1]大于a[3]则交换两者的值,否则不变。再比较a[1]与a[4],以此类推,最后比较a[1]与a[n]的值。这样处理一轮后,a[1]的值一定是这组数据中最小的。再将a[2]与a[3]~a[n]以相同方法比较一轮,则a[2]的值一定是a[2]~a[n]中最小的。再将a[3]与a[4]~a[n]以相同方法比较一轮,以此类推。共处理n-1轮后a[1]、a[2]、……a[n]就以升序排列了。
  优点:稳定,比较次数与冒泡排序一样;
  缺点:相对之下还是慢。
  
三、插入排序
  已知一组升序排列数据a[1]、a[2]、……a[n],一组无序数据b[1]、b[2]、……b[m],需将二者合并成一个升序数列。首先比较b[1]与a[1]的值,若b[1]大于a[1],则跳过,比较b[1]与a[2]的值,若b[1]仍然大于a[2],则继续跳过,直到b[1]小于a数组中某一数据a[x],则将a[x]~a[n]分别向后移动一位,将b[1]插入到原来a[x]的位置这就完成了b[1]的插入。b[2]~b[m]用相同方法插入。(若无数组a,可将b[1]当作n=1的数组a)
  优点:稳定,快;
  缺点:比较次数不一定,比较次数越少,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决这个问题。
  
四、缩小增量排序
  由希尔在1959年提出,又称希尔排序(shell排序)。
  已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。发现当n不大时,插入排序的效果很好。首先取一增量d(d<n),将a[1]、a[1+d]、a[1+2d]……列为第一组,a[2]、a[2+d]、a[2+2d]……列为第二组……,a[d]、a[2d]、a[3d]……列为最后一组以次类推,在各组内用插入排序,然后取d'<d,重复上述操作,直到d=1。
  优点:快,数据移动少;
  缺点:不稳定,d的取值是多少,应取多少个不同的值,都无法确切知道,只能凭经验来取。
  
五、快速排序
  快速排序是冒泡排序的改进版,是目前已知的最快的排序方法。
  已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先任取数据a[x]作为基准。比较a[x]与其它数据并排序,使a[x]排在数据的第k位,并且使a[1]~a[k-1]中的每一个数据a[x],然后采用分治的策略分别对a[1]~a[k-1]和a[k+1]~a[n]两组数据进行快速排序。
  优点:极快,数据移动少;
  缺点:不稳定。
  
六、箱排序
  已知一组无序正整数数据a[1]、a[2]、……a[n],需将其按升序排列。首先定义一个数组x[m],且m>=a[1]、a[2]、……a[n],接着循环n次,每次x[a]++.
  优点:快,效率达到O(1)
  缺点:数据范围必须为正整数并且比较小
  
七、堆排序
  先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区
  再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key
  由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。
  ……
  直到无序区只有一个元素为止。
优点:快,时间稳定;
缺点:同样大的数顺序不稳定

在C++排序中,最常用、最好用的有

  1. 冒泡排序(bubble sort),时间复杂度为O(n^2);

  2. 鸡尾酒排序(Cocktail sort,双向的冒泡排序),时间复杂度为O(n^2);

  3. 快速排序(Quick sort,是对冒泡排序的一种改进),时间复杂度下界为O(nlogn),最坏情况为O(n^2);

  4. 插入排序(insertion sort),时间复杂度为O(n^2);

  5. 希尔排序(Shell Sort,插入排序的一种,也称缩小增量排序),时间复杂度为O(nlog n) ;

  6. 选择排序(selection sort),时间复杂度为O(n^2);

  7. 堆排序(Heap sort,选择排序的一种。),时间复杂度为O(nlog n);

  8. 归并排序(Merge sort),时间复杂度为O(nlog n);

  9. 基数排序(radix sort),时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数

在C++中有排序函数sort(),包含在<algorithm> 中,参数格式为

sort(a+begin,a+end);

其中begin表示所需要排序的数组a的开头,end则表示所需要排序的数组a的最后一个元素的位置。



排序大类分为内排序和外排序,通常排序指的是内排序
内排序主要分为:
插入排序(直接插入排序,折半插入排序,Shell排序)
交换排序(冒泡排序,快速排序)
选择排序(简单选择排序,堆排序)
归并排序
基数排序
每种排序根据问题的规模以及初始排序表排列情况性能而不同,一般来讲,快速排序的平均性能最好。在C++中,可以使用标准库算法中的sort进行排序,它会根据情况动态地选择一种高效排序算法。

通常有插入,冒泡,桶,交换排序,堆排序,根据数据量大小各有优缺点。STL提供的快速排序能够动态的根据数量多少选择经验上最恰当的排序算法,所以std::sort是集成了所有排序有点的最好排序算法

冒泡排序O(n2),快速排序(常有),归并排序(较好),选择排序,插入排序。具体排序实现百度之


10000个数据,哪种排序算法比较快呢?
数据表中有10000个元素,如果仅要求求出其中最大的10个元素,则采用堆排序最节省时间。堆排序是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点;在堆的数据结构中,堆中的最大值总是位于根节点(...

的排序方法中,采用哪种方法最好
这个各取所需,根据不同的需要选取不同的方法。我们通常所说的排序算法往往指的是内部排序算法,即数据记录在内存中进行排序。排序算法大体可分为两种:一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等。另一种是非比较排序,...

常见的排序算法哪个效率最高?
希尔排序。2.选择排序:简单选择排序、堆排序。3.交换排序:冒泡排序、快速排序。4.归并排序。5.基数排序。java中的算法,一共有多少种,哪几种,怎么分类?1、算法按实现方式分,有递归、迭代、平行、序列、过程、确定、不确定等。2、算法按设计范型分,有分治、动态、贪心、线性、图论、简化等。

几种排序算法的比较
插入排序、冒泡排序、选择排序的时间复杂性为O(n2)其它非线形排序的时间复杂性为O(nlog2n)线形排序的时间复杂性为O(n);3.辅助空间的比较 线形排序、二路归并排序的辅助空间为O(n),其它排序的辅助空间为O(1);4.其它比较 插入、冒泡排序的速度较慢,但参加排序的序列局部或整体有序时,这种排序...

平台行业词云分析中有哪几种排序方式
一般在面试中最常考的是快速排序和归并排序,并且经常有面试官要求现场写出这两种排序的代码。 对这两种排序的代码一定要信手拈来才行。还有插入排序、冒泡排序、堆排序、基数排序、桶排序等。常见的几种算法:①冒泡算法 ②选择排序 ③插入排序 ④快速排序 常见问题 问题一:各种排序算法用JavaScript 如何...

目前汉字排序有哪几种方法?它们各有什么优、缺点?
一共有3种.内容排序 拼音排序 部首排序 内容排序的优、缺点:优点是可以迅速根据字义的归类来找到某字.缺点是如果不知道字义就不能用这个方法查了.比如:“亿”属于数量类;“车”属于交通类.拼音排序的优、缺点: 优点是可以迅速根据某字的拼音来找到某字.如果不知道拼音就不能用这个方法查了.部...

程序员实用算法有哪些推荐算法一:快速排序算法
程序员实用算法有用推荐 算法一: 快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要O(nlog n)次比较。在最坏状况下则需要O(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他O(n log n) 算法更快,因为它的内部循环 (inner loop)可以在...

几种排序方法的解释
通常拿出的这个元素都是序列中的第一个,因为这样比较简单,不用思考。举例: 4,2,7,5 第一次整理为:2,(4),7,5 冒泡排序就是相邻元素的两个两个比较,第一个第二个比较,大的放在第二个,第二个第三个比较,大的放在第三个……从左到右来一次,就会有一个最大的被找到而放在了...

句子排序方法有哪几种
1.首先我们要给我们的句子排序有两种形式,一是把错乱的句子整理通顺。二是把前面表上序号。2.理解了句子的顺序,要认真读懂每个句子的意思,想一想具体说的是什么内容,理解透彻 3.确定句子的根据来整理,然后排列。排列句子和句子之间的意思。找到对的开头和结尾。4.找到句子的第一句,然后读懂每一句的...

上万个无序的数据用哪种排序可以最快找到最大值
建议使用快速排序或堆排序。如果在外存储器中,可使用归并排序。但是快速排序有一个栈的问题.如果数据再多的话,要防止栈溢出!基本上快速排序是比较快的.也可以考虑一下Shell排序.还有一点,如果你的数据是基本有序或者部分有序,不要使用快速排序,不然这种排序的速度跟冒泡排序没有什么区别 ...

敦煌市13114086249: C++排序有哪几种最常用,最好用? -
唱佳陈香: 在C++排序中,最常用、最好用的有 1. 冒泡排序(bubble sort),时间复杂度为O(n^2);2. 鸡尾酒排序(Cocktail sort,双向的冒泡排序),时间复杂度为O(n^2); 3. 快速排序(Quick sort,是对冒泡排序的一种改进),时间复杂度下界为O(...

敦煌市13114086249: C++排序有哪几种最常用,最好用? -
唱佳陈香: 排序大类分为内排序和外排序,通常排序指的是内排序内排序主要分为:插入排序(直接插入排序,折半插入排序,Shell排序)交换排序(冒泡排序,快速排序)选择排序(简单选择排序,堆...

敦煌市13114086249: 在C++中数组的排序方法有哪些? -
唱佳陈香: 大体上可以分为四类:插入排序,选择排序和交换排序; 插入排序有:直接插入排序,希尔排序; 选择排序有:直接选择排序,堆排序 交换排序有:冒泡排序,快速排序 如果数组比较大的话也可用归并排序,效率比较高 各种排序方法各有所长,有的效率比较高,有的空间消耗比较小,总的来说,要针对不同的问题选择合适的方法; 另外,我有各种排序的源代码需要的话留下邮箱.是我以前学的时候写的!

敦煌市13114086249: C++有什么好用的排序方法,要高效的~进来看~ -
唱佳陈香: 数据量大的话,可以采用快速排序, 如果你要匹配10这个值,而数组是无序的,那么只能通过一个个比较 二分法数组一定要有序

敦煌市13114086249: c++几种常见的排序程序 -
唱佳陈香: (1)“冒泡法” 冒泡法大家都较熟悉.其原理为从a[0]开始,依次将其和后面的元素比较,若a[0]>a[i],则交换它们,一直比较到a[n].同理对a[1],a[2],...a[n-1]处理,即完成排序.下面列出其代码:void bubble(int *a,int n) /*定义两个参数:数组首地...

敦煌市13114086249: 几种经典排序算法优劣比较的C++程序实现 -
唱佳陈香: 一、低级排序算法1.选择排序 (1)排序过程 给定一个数值集合,循环遍历集合,每次遍历从集合中选择出最小或最大的放入集合的开头或结尾的位置,下次循环从剩余的元素集合中遍历找出最小的并如上操作,最后直至所有原集合元素都遍历...

敦煌市13114086249: C++数组排序有哪几种算法? -
唱佳陈香: 插入排序算法1.从有序数列和无序数列{a2,a3,…,an}开始进行排序;2.处理第i个元素时(i=2,3,…,n) , 数列{a1,a2,…,ai-1}是已有序的,而数列{ai,ai+1,…,an}是无序的.用ai与ai-1,a i-2,…,a1进行比较,找出合适的位置将ai插入;3.重复第二...

敦煌市13114086249: C++排序的类型
唱佳陈香: 冒泡排序:在最优情况下只需要经过n- 1次比较即可得出结果,(这个最优情况那就是序列己是正序,从100K的正序结果可以看出结果正是如此),但在最坏情况下,即倒序(或一个较小值在最后),下沉算法将需要n(n-1)/2次比较.所以一般...

敦煌市13114086249: 在C++中有哪些排序法? -
唱佳陈香: 本人学习数据结构时看到的不错的总结,共享一下了 文件有一组记录组成,记录有若干数据项组成,唯一标识记录的数据项称关键字; 排序是将文件按关键字的递增(减)顺序排列; 排序文件中有相同的关键字时,若排序后相对次序保持不变...

敦煌市13114086249: C++中的排序法有哪些??查找法又有哪些?? -
唱佳陈香: 概述 内排序的方法有许多种,按所用策略不同,可归纳为五类:插入排序、选择 排序、交换排序、归并排序和分配排序.其中,插入排序主要包括直接插入排序和希尔排序两种;选择排序主要包括直接选择排序和堆排序;交换排序主要包括...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网