冒泡、直插、选择、快速、希尔、归并排序算法进行比较

作者&投稿:愈学 (若有异议请与网页底部的电邮联系)
(1)冒泡、直插、选择、快速、希尔、归并排序算法进行比较; (2)待排序的元素的关键字为整数。其中的数~

1.冒泡排序已知一组无序数据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]就以升序排列了。 优点:稳定,比较次数已知;缺点:慢,每次只能移动相邻两个数据,移动数据的次数多。 初始关键字 [49 3865 97 76 13 27 49]第一趟排序后 [38 4965 76 13 27 49] 97第二趟排序后 [38 4965 13 27 49] 76 97第三趟排序后 [38 4913 27 49] 65 76 97第四趟排序后 [38 1327 49] 49 65 76 97第五趟排序后 [38 1327] 49 49 65 76 97第六趟排序后 [13 27]38 49 49 65 76 97第七趟排序后 [13] 2738 49 49 65 76 97最后排序结果 13 2738 49 49 76 76 97 #include using namespace std;void main() { int i,j,k; int a[8]={49,38,65,97,76,13,27,49}; for(i=7;i>=0;i--) { for(j=0;ja[j+1]) { k=a[j]; a[j]=a[j+1]; a[j+1]=k; } } } for(i=0;iusing namespace std;void main(){ int i,j,k,t; int R[8]={49,38,65,97,76,13,27,49}; for(i=0;i<7;i++) { k=i; for(j=i+1;j<8;j++) if(R[j]<R[k]) k=j; if(k!=i) { t=R[j];R[j]=R[k];R[k]=t; } }for(i=0;i<8;i++) cout<<R<<endl; }

3.插入排序已知一组,一组无序数据b[1]、b[2]、……b[m],需将其变成一个升序数列。先创建一个变量a。首先将不b[1]与b[2],如果b[1]大于b[2]则交换位置,否则不变;再比较b[2]与b[3],如果b[3]小于b[2],则将b[3]赋值给a,再将a与b[1]比较,如果a小于b[1];则将b[2],b[1]依次后移;在将a放在b[1]处以此类推,直到排序结束。初始关键字 [49 3865 97 76 13 27 59] a b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8]1-----49 49 > 38 65 97 76 13 27 5938 49 49 ……….38 38 49 ……….2-----38 38 49 76 13 27 5976 38 49 65 97 97……..76 38 49 65 76 97……..以此类推void insertSort(Type* arr,long len){ long i=0,j=0; for(i=1;i0) { arr[j]=arr[j-1]; j--; } arr[j]=tmpData; }}4.缩小增量排序(希尔排序)由希尔在1959年提出,又称希尔排序。已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。发现当n不大时,插入排序的效果很好。首先取一增量d(dusing namespace std;#define MAX 16 void shell_sort(int *x, int n){ inth, j, k, t; for(h=n/2;h>0; h=h/2) /*控制增量*/ { for(j=h; j=0 && t>*p++; p=a; shell_sort(p,MAX); for(p=a, i=0; i<MAX; i++) { cout<<*p++<<endl; } cout<<endl;}

5.快速排序快速排序是冒泡排序的改进版,是目前已知的最快的排序方法。已知一组无序数据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]两组数据进行快速排序。优点:极快,数据移动少;缺点:不稳定。分段插入排序void QuickSort(int *pData, int left, intright){int i, j;int middle,iTemp;i = left;j = right;middle =pData[(left + right) / 2]; //求中间值do{while((pData middle) && (j > left)) //从右扫描小于中值的数j--;if (i i),递归右半边if(right>i)QuickSort(pData,i,right);} 6.归并排序算法合并排序(MERGESORT)是又一类不同的排序方法,合并的含义就是将两个或两个以上的有序数据序列合并成一个新的有序数据序列,因此它又叫归并算法。它的基本思想就是假设数组A有N个元素,那么可以看成数组A是又N个有序的子序列组成,每个子序列的长度为1,然后再两两合并,得到了一个 N/2 个长度为2或1的有序子序列,再两两合并,如此重复,值得得到一个长度为N的有序数据序列为止,这种排序方法称为2—路合并排序。例如数组A有7个数据,分别是: 49 38 65 97 76 13 27,那么采用归并排序算法的操作过程如图7所示:初始值 [49] [38] [65] [97] [76] [13] [27]第一次合并之后 [38 49] [65 97] [13 76] [27]第二次合并之后 [38 49 65 97] [13 27 76]第三次合并之后 [13 27 38 49 65 76 97]合并算法的核心操作就是将一维数组中前后相邻的两个两个有序序列合并成一个有序序列。合并算法也可以采用递归算法来实现,形式上较为简单,但实用性很差。合并算法的合并次数是一个非常重要的量,根据计算当数组中有3到4个元素时,合并次数是2次,当有5到8个元素时,合并次数是3次,当有9到16个元素时,合并次数是4次,按照这一规律,当有N个子序列时可以推断出合并的次数是X(2 >=N,符合此条件的最小那个X)。其时间复杂度为:O(nlogn).所需辅助存储空间为:O(n)归并排序:#include void merge(int a[],int p,int q,int r){int n1=q-p+1,n2=r-q,i,j,k;int l[1002],R[1002];for (i=1;i<=n1;i++)l=a[p+i-1];for (j=1;j<=n2;j++)R[j]=a[q+j];R[n2+1]=l[n1+1]=999999;i=j=1;for (k=p;k<=r;k++){if (l<=R[j]){a[k]=l;i++;}else{a[k]=R[j];j++;}}}void mergesort(int a[],int p,int r){int q;if (p<r){q=(p+r)/2;mergesort(a,p,q);mergesort(a,q+1,r);merge(a,p,q,r);}}int main(){int a[1001],t,n,i;scanf("%d",&t);while (t--){scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d",&a);mergesort(a,1,n);for (i=1;i<=n;i++){printf("%d",a);if (i!=n)printf(" ");}printf("
");}return 0;}

直接插入排序
说明:逐个将后一个数加到前面的排好的序中。在直接插入排序过程中,对其中一个记录的插入排序称为一次

排序;直接插入排序是从第二个记录开始进行的,因此,长度为n的记录序列需要进行n-1次排序才能完成整个

序列的排序。时间复杂度为O(n2)。
void InsertSort(elemtype x[],int n)
/*用直接插入法对x[0]-x[n-1]排序*/
{
int i,j;
elemtype s;
for(i=0;i<n-1;i++)
{
s=x[i+1];
j=i;
while(j>-1&&s.key<x[j].key)
{
x[j+1]=x[j];
j--;
}
x[j+1]=s;
}
}

---------------------
希尔排序
说明:希尔排序又称缩小增量排序,增量di可以有各种不同的取法,但最后一次排序时的增量必须为1,最简

单可取di+1=di/2(取小)。时间复杂度为O(n(log2n)2)。

void ShellSort(elemtype x[],int n,intd[],int Number)
/*用希尔排序法对记录x[0]-x[n-1]排序,d为增量值数组*/
/*Number为增量值个数,各组内采用直接插入法排序*/
{
int i,j,k,m,Span;
elemtype s;
for(m=0;m<Number;m++)
{
Span=d[m];
for(k=0;k<Span;k++)
{
for(i=k;i<n-1;i+=Span)/*这个for之后的是“组内采用直接插入法排序”*/
{
s=x[i+Span];
j=i;
while(j>-1&&s.key<x[j].key)
{
x[j+Span]=x[j];
j-=Span;
}
x[j+Span]=s;
}
}
}
}

----------------------------
直接选择排序
说明:每次将后面的最小的找出来插入前面的已排好的序中。同理,具有n个记录的序列要做n-1次排序。
时间复杂度为O(n2)。
void SelectSort(elemtype x[],int n)
/*用直接选择排序法对x[0]-x[n-1]排序*/
{
int i,j,Small;
elemtype Temp;
for(i=0;i<n-1;i++)
{
Small=i;
for(j=i+1;j<n;j++)
if(x[j].key<x[Small].key)
Small=j;

if(Small!=i)
{
Temp=x[i];
x[i]=x[Small];
x[Small]=Temp;
}
}
}

--------------------------
冒泡排序
说明:两个两个比较,将大的往后移。通过第一次冒泡排序,使得待排序的n个记录中关键字最大的记录排到

了序列的最后一个位置上。然后对序列中前n-1个记录进行第二次冒泡排序。。。对于n个记录的序列,共需进

行n次冒泡排序。时间复杂度为O(n2)。

void BubbleSort(elemtype x[],int n)
/*用冒泡排序法对x[0]-x[n-1]排序*/
{
int i,j,flag=1;
elemtype Temp;
for(i=1;i<n&&flag==1;i++)
{
flag=0;
for(j=0;j<n-i;j++)
{
if(x[j].key>x[j+1].key)
{
flag=1;
Temp=x[j];
x[j]=x[j+1];
x[j+1]=Temp;
}
}
}
}

-----------------------------
快速排序
说明:又叫分区交换排序,是对冒泡排序方法的一种改进。时间复杂度为O(nlog2n)。

void QuickSort(elemtype x[],int low,int high)
/*用递归方法对记录x[0]-x[n-1]进行快速排序*/
{
int i,j;
elemtype Temp;

i=low;
j=high;
Temp=x[low];

while(i<j)
{
/*在序列的右端扫描*/
while(i<j&&Temp.key<=x[j].key)j--;
if(i<j)
{
x[i]=x[j];
i++;
}

/*在序列的左端扫描*/
while(i<j&&x[i].key<Temp.key)i++;
if(i<j)
{
x[j]=x[i];
j--;
}
}
x[i]=Temp;

/*对子序列进行快速排序*/
if(low<i-1)QuickSort(x,low,i-1);
if(j+1<high)QuickSort(x,j+1,high);
}

-------------------------
归并排序
说明:所谓归并排序就是将两个或两个以上的有序数据序列合并成一个有序数据序列的过程。
时间复杂度为O(nlog2n)。

void merge(r,l,m,h,r1,r2)/*r[l,m]及r[m+1,h]分别有序,归并后置于r2中*/
sqlist r,r2;
int l,m,h;
{
int i,j,k;
k=l;/*k是r2的指示器,i、j分别为s1、s2的指示器*/
i=l;
j=m+1;

while(i<=m&&j<=h)
{
if(r[i].key<=r[j].key)
{
r2[k]=r[i];
i++;
}
else
{
r2[k]=r[j];
j++;
}
k++;
}
if(i>m) /*s1结束*/
while(j<=h)
{
r2[k]=r[j];
j++;k++;
}
else
while(i<=m)
{
r2[k]=r[i];
i++;k++;
}
}

(1)冒泡排序

冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

(2)选择排序

选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。

(3)插入排序
插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

(4)快速排序
快速排序有两个方向,左边的i下标一直往右走,当a[i] <= a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j, 交换a[i]和a[j],重复上面的过程,直到i>j。交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为 5 3 3 4 3 8 9 10 11,现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j] 交换的时刻。

(5)归并排序
归并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也没有人故意交换,这不会破坏稳定性。那么,在短的有序序列合并的过程中,稳定是是否受到破坏?没有,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。

(6)基数排序
基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序,最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以其是稳定的排序算法。

(7)希尔排序(shell)
希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

(8)堆排序
我们知道堆的结构是节点i的孩子为2*i和2*i+1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。在一个长为n 的序列,堆排序的过程是从第n/2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。但当为n/2 -1, n/2-2, ...1这些个父节点选择元素时,就会破坏稳定性。有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,那么这2个相同的元素之间的稳定性就被破坏了。所以,堆排序不是稳定的排序算法。


扦插有直插和斜插如果插穗长度不同用直插和斜插以后又什么区别_百度知 ...
这要看你是插在土里的还是插在水里的,插在土里的一般插穗都比较短,而且都是斜插,这样有利于插条底部斜面更大面积的与土壤结合,有利于提早发根,发壮根.若是插在水里的,一般选择的都是长茎的花瓶,这样要求的插穗就不较长,而且要求是直插,这样可以减小受伤面积,也有利于水分的吸收....

插根育苗的方法是什么?
6. 根插穗应在背风阴凉处截制,长度约为15厘米,上端平截,下端斜切,以便正确插入并避免倒插。7. 插根可在春季或秋季进行。秋插应在根穗剪截后立即进行,而春插则在土壤解冻后开始,根穗发芽前结束。8. 插根有直插、斜插和平埋三种方法,通常优先选择直插。平埋法可能导致根系发育不良,多在...

发财树如何扦插,锯断会生根吗
处理插条:插条要选没有病虫害且当年生的,最好是木质化的。长度大概在6-7公分左右就行,下端的切口要成斜面,且要光滑,这样的更容易愈合。处理好之后放在生根溶液里浸泡一天,这样能促使更快生根。进行扦插:插条处理好之后就可扦插入土,直接将插条插入基质中即可,可斜插也可直插,大概入土三公分...

花卉有没有系统的扦插的方法?资料
虎尾兰为肉质剑形叶,可横切成5厘米左右的叶段为插穗,直插于沙中,插时上下不要颠倒,可在基部发生新根,形成新植株。叶芽插:橡皮树、八仙花、茉莉花、扶桑等在叶插时,其叶柄和叶腋虽能生根,但不能发芽,所以,不能生长成新植株。因此,要选用基部带有一个腋芽的叶片扦插,才能发育成新植株。...

杨树苗要怎样栽培
杨树的栽培技术: 杨树苗繁殖主要通过扦插。扦插繁殖方法:一、种条选择:选用优质种条选用一年生扦插苗,以一级苗和二级苗中下部分作种条为宜。三级苗发育不健全不能作种条二级苗,梢部木质化程度差的部分和有病虫危害的苗木不能作种条。二、扦插:剪截插穗及处理剪截插穗长16cm-18cm,芽口距...

直插LED的特性有哪些?
LED的发光原理就是将电流通过化合物半导体,通过电子与空穴的结合,过剩的能量将以光的形式释出,达到发光的效果。用于可见光的发光二极体的波长在400 - 700 nm。直插LED的亮度不同,价格不同。灯杯:一般亮度为60-70 lm;球泡灯:一般亮度为80-90 lm。1W红光,亮度一般为30-40 lm;1W绿光,亮度一般...

停电自亮的家用15W的节能灯泡,充电方法是将灯泡的插头直插电源插...
氖泡是在小玻璃泡中充入惰性气体,电离发光。 串联降压限流电阻选择:实测插座LED指示灯串联电阻为80KΩ~100KΩ,功率0.25W。实际上电阻功率太小,经常烧断,建议采用2W左右比较安全。氖泡串联电阻为1MΩ左右,功率0.25W可以满足要求。 扩展资料: 在发光管上应该并联一只反向二极管,但是我看好多电器上...

怎样扦插沙树
可选择粗壮、芽泡满的枝条剪成15-20 厘米长的茎段.剪条时,上切口在芽的上部o.5-1处剪断, 下部切口和芽的距离则随植物不同而不同;有些如带一小段老枝或是分枝条带—小段主枝形似马蹄,即插条带踵条。更易生根.同外苗圃在插条剪好后,在捅条的基部用修枝剪顺着枝条的方向划几道伤口。增...

直插LED灯PCB板可以直接浸泡在洗板水中清洗吗?
单纯的一块PCB板应该是可以的,但洗完之后一定要保证完全干燥后方可使用。

花卉扦插
在同一植株上,插材要选择中上部,向阳充实的枝条,且节间较短,芽头饱满,枝叶粗壮。在同一枝条上,硬...常选自母株茎基附近中等粗细的侧根,截取长约5~10cm,直插或斜插于基质中,扦插时上、下的方向不可...四季海棠,夹竹桃等,插条剪取后可先泡在清水中,等泡出根来即可直接栽入盆中。月季,米兰等,可将插条...

元宝山区17038053670: C语言排序的方法 -
臾疯康复: 现在流行的排序有:直接插入排序、冒泡排序、简单选择排序、希尔排序、快速排序、堆排序、归并排序、基数排序.对n个记录进行选择排序的方法是:通过n-i次关键字之间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)...

元宝山区17038053670: 写出你所知道的3种常用的排序方法,并用其中一种方法设计出程序为数组a[100]排序. -
臾疯康复: 常用的排序算法有很多: 冒泡,快速排序,直接插入,希尔排序,选择排序,堆排序,归并排序! 就举冒泡排序(c++): void bubblesort() {for (i=0;i<max;i++){for(j=l;j>=i+1;j--)if(a[j]<a[j-1]) //小则交换{a[0]=a[j];a[j]=a[j-1];a[j-1]=a[0];}} } 以上意见仅供参考!

元宝山区17038053670: 待排序序列{44,77,55,99,66,33,22,88,77'} 直接插入排序 希尔排序 冒泡排序 快速排序 直接选择排序 归并 -
臾疯康复: / 希尔排序 { int i,j,gap; int temp; gap=n/,int n) // 冒泡排序 { int i,j; int temp; for(i=0; while(temp=i+1;i++) { j=i-gap; while(j>=gap) if(A[j]> for(i=1;i j=j-gap; } else j=0; } gap=gap/,int n) /0) { for(i=gap;i

元宝山区17038053670: C++中的排序法有哪些??查找法又有哪些?? -
臾疯康复: 概述 内排序的方法有许多种,按所用策略不同,可归纳为五类:插入排序、选择 排序、交换排序、归并排序和分配排序.其中,插入排序主要包括直接插入排序和希尔排序两种;选择排序主要包括直接选择排序和堆排序;交换排序主要包括...

元宝山区17038053670: 对序列1,2,3,4,5进行排序,用堆排序、快速排序、冒泡排序和归并排序进行排序,分别需要进行几趟排序 -
臾疯康复: 1、插入排序(直接插入排序和希尔排序) 2、选择排序(直接选择排序和堆排序) 3、交换排序(冒泡排序和快速排序) 4、归并排序 5、基数排序 直接插入排序:逐个将后一个数加到前面的排好的序中.在直接插入排序过程中,对其中一个记...

元宝山区17038053670: 数据结构课程设计 - 内部排序算法时间的比较 -
臾疯康复: 用系统计时器算时间复杂度. #include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #define LIST_INIT_SIZE 50000 int bj1,yd1,n; clock_t start_t,end_t; typedef struct { int key; }ElemType; typedef struct { ElemType *elem; int ...

元宝山区17038053670: 电脑排序方法有哪些 -
臾疯康复: 五大类方法:插入排序(直接插入排序、希尔排序等)、快速排序(冒泡排序、快速排序)、选择排序(简单选择排序、树形选择排序、堆排序)、归并排序、基数排序

元宝山区17038053670: 年份日期之类的自然数作用是排序还是标号? -
臾疯康复: 日期有其本身的格式,但其存储时是以序数号存储的,不同的系统起点可能不同,一般以1900年1月1日为序数1,每增加1天,序数加1,如1900年1月28日,序数就是28,2019年8月29日的序数是43706.因此日期的实质还是数,可排序也可计算...

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

元宝山区17038053670: 数据结构的排序算法中,哪些排序是稳定的,哪些排序是不稳定的? -
臾疯康复: 快速排序、希尔排序、堆排序、直接选择排序不是稳定的排序算法 基数排序、冒泡排序、直接插入排序、折半插入排序、归并排序是稳定的排序算法

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