1、8种排序算法Ultimate8种排序算法(有代码)个人对这8种排序算法的理解,希望对大家有点帮助.趁自修时间,自己将这8种排序的代码写了一下.1.简单的选择排序bool selectionsort(int *array,int n) /array为存储数据的数组,n为数组元素个数int k,temp; /k用来存储,临时最小数据的位置for(int i=0;in-1;i+) k=i; for(int j=i+1;jn;j+) /从第i个数开始选择最小数位置,存于k中 if(arrayjarrayk) k=j;if(k!=i) /若最小数,不为arrayi,则arrayi与arrayk进行交换
2、temp=arrayi; arrayi=arrayk; arrayk=temp;return true;思想:逐个找出,第一小,第二小.第n小的数.算法平均时间复杂度: O(n2)2.插入排序bool insertionsort(int *array,int n)int temp; /用来存储,插入的数据for(int i=1;i=0;j-)/逐个向前寻找插入点 if(temparrayj)/找到,跳出循环 break; else /没找到,将前一个数据后移 arrayj+1=arrayj;arrayj+1=temp;return true;思想: 逐个取数,插入一个有序数组(从后向前插)算法
3、平均时间复杂度: O(n2)3.自底向上排序bool bottomupsort(int *array,int n)int length=1,temp_length,i; /temp_length表示单个合并数组的长度while(lengthn)temp_length=length; /length表示合并后数组的长度 length=2*temp_length; i=0; /i用于记录合并数组的起始位置while(i+length-1=n-1) merge(array,i,i+temp_length,i+length-1);/合并ii+temp_length-1 和 i+temp_lengthi
4、+length-1 段 i=i+length; /取下一个合并段的起始位置if(i+temp_lengthn-1) merge(array,i,i+temp_length,n-1); /对尾部剩余段合并return true;bool merge(int *array,int start1,int start2,int n)/合并两个有序数组int temp_n=n-start1+1, /两合并数组的长度和*temp_array, n1=start2-1, /第一个有序数组的末端位置temp_start1=start1; /记录start1的初始位置temp_array=(int *)mall
5、oc(sizeof(int)*temp_n); /申请长度为temp_n的整形空间,用于临时存储合并后的数组 for(int i=0;start1=n1&start2=n;i+) /对两个有序数组进行合并,存储于temp_arrayif(arraystart1=arraystart2) temp_arrayi=arraystart1; start1+;else temp_arrayi=arraystart2; start2+;if(start1=n1) while(start1=n1) temp_arrayi+=arraystart1; start1+;elsewhile(start2=n)
6、temp_arrayi+=arraystart2; start2+;for(i=0,start1=temp_start1;itemp_n;start1+,i+) /将合并后的有序数组,复制到array数组中arraystart1=temp_arrayi;free(temp_array);return true;思想: 将数组的个部分,两两有序数组进行合并算法平均时间复杂度: O(nlogn)4.快速排序void QuickSort(int low,int high,int *array)int pos;if(lowhigh)pos=SPLIT(low,high,array); /以arrayl
7、ow进行划分,pos最为划分点 /前一部分arraylow,后一部分,反之QuickSort(low,pos-1,array); /对划分后的前一部分递归处理QuickSort(pos+1,high,array); /对划分后的后一部分递归处理 int SPLIT(int low,int high,int *array)int temp=arraylow; /用temp来记录划分数while(lowtemp&lowhigh) /寻找小于temp的数 high-;if(low=high) break;else arraylow=arrayhigh; low+;while(arraylowtemp
8、&lowhigh) /寻找大于temp的数 low+;if(low=high) break;else arrayhigh=arraylow; high-;arraylow=temp; /最终low=high作为划分点,并将划分数存于arraylowreturn low;思想:就是你 从数组中 任取一个元素 p (可随机取,现在以取第一个为例)以P作为主元,对数组 进行划分 ,前一部分小于 P,后一部分 大于p最后 划分处 存储 p然后分别对划分后的前一部分 和 后一部分 递归调用算法平均时间复杂度: O(nlogn)5.归并排序bool MergeSort(int low,int high,i
9、nt *array)int middle=(high+low)/2; /将数组划分为2分if(lowhigh)MergeSort(low,middle,array); /对前一部分进行递归处理MergeSort(middle+1,high,array); /对后一部分进行递归处理HeBing(low,middle,middle+1,high,array); /将排序后的,前后两部分,进行合并return true;bool HeBing(int low1,int high1,int low2,int high2,int *array)int *temp,i=low1,j=low2,k=0;te
10、mp=(int *)malloc(high2-low1+1)*sizeof(int); /temp用于临时存储合并后的数组while(i=high1&j=high2) /对两个有序数组进行合并if(arrayiarrayj) tempk+=arrayi; i+;else tempk+=arrayj; j+; if(i=high1)while(i=high1) tempk+=arrayi+;elsewhile(j=high2) tempk+=arrayj+;for(i=low1,j=0;i=high2;i+,j+) /将合并后的数组,复制到array中arrayi=tempj;free (tem
11、p);return true;思想: 将数组划分为小数组,通过局部的有序合并,解决问题算法平均时间复杂度: O(nlogn)6.冒泡排序bool bubblesort(int *array,int n)int flag=1, /用来标记是否发生交换temp;for(int i=0;in-1;i+)for(int j=i+1;jn;j+) if(arrayjarrayj-1) temp=arrayi; arrayi=arrayj; arrayj=temp; flag=0; if(flag) /如果flag为真,及没发生交换,直接跳出循环 break;else flag=1;return true
12、;思想: 相邻两数比较,小数放前面算法平均时间复杂度: O(n2)7.堆排序bool slipdown(int *array,int cur,intn)for(int next=2*cur;next=n;next=2*cur) /next表示cur的左孩子if(nextn&arraynextarraynext+1) /取cur的两个孩子的大者 next+;if(arraynext0;i-) /将数组调整为大顶堆slipdown(array,i,n);for(int N=n;N1;N-) /选出堆中最大元,存于N位置,循环进行temp=arrayN;arrayN=array1;array1=te
13、mp;slipdown(array,1,N-1);return true;思想: 用二叉树的结构来表示数组,及用数组来表示二叉树的结构,比如i为父节点其孩子为,2i,和2i+1 其中,大顶堆中 父节点大于其两个孩子算法平均时间复杂度: O(nlogn)8.基数排序bool radixsort(int *array,int n)L TENL10; /其中TENLm.number中存储,数据的第i位为m的数据int k;for(int i=0;i10;i+)TENLi.n=0;for(i=1;i=5;i+) /这里假设 数据都 小于100000,对数据进行五次分配for(int j=0;jn;j+
14、) /对数据进行分配 k=getnum(arrayj,i); TENLk.numberTENLk.n=arrayj; TENLk.n+;j=0;for(k=0;k10;k+) /将此次分配后的数据,按顺序重新置入array中 for(int m=0;mTENLk.n;m+) arrayj+=TENLk.numberm; TENLk.n=0;return true;intgetnum(int num,int i) /从个位起,获得num的第i为数据int temp=1;for(int j=0;ji;j+)temp=temp*10;return (num%temp-num%(temp/10)/(t
15、emp/10);思想:先从数据的低位开始,进行分配,分成10个空间,分别存储位为,0,1,2,3.9 重复的对次地位操作,知道预定的高位,排序完成8种排序算法个人对这8种排序算法的理解,希望对大家有点帮助.趁自修时间,自己将这8种排序的代码写了一下.1.简单的选择排序思想:逐个找出,第一小,第二小.第n小的数.算法平均时间复杂度: O(n2)2.插入排序思想: 逐个取数,插入一个有序数组(从后向前插)算法平均时间复杂度: O(n2)3.自底向上排序思想: 将数组的个部分,两两有序数组进行合并算法平均时间复杂度: O(nlogn)4.快速排序思想:就是你 从数组中 任取一个元素 p (可随机取,
16、现在以取第一个为例)以P作为主元,对数组 进行划分 ,前一部分小于 P,后一部分 大于p最后 划分处 存储 p然后分别对划分后的前一部分 和 后一部分 递归调用算法平均时间复杂度: O(nlogn)5.归并排序思想: 将数组划分为小数组,通过局部的有序合并,解决问题算法平均时间复杂度: O(nlogn)6.冒泡排序思想: 相邻两数比较,小数放前面算法平均时间复杂度: O(n2)7.堆排序思想: 用二叉树的结构来表示数组,及用数组来表示二叉树的结构,比如i为父节点其孩子为,2i,和2i+1 其中,大顶堆中 父节点大于其两个孩子算法平均时间复杂度: O(nlogn)8.基数排序思想:先从数据的低位
17、开始,进行分配,分成10个空间,分别存储位为,0,1,2,3.9 重复的对次地位操作,知道预定的高位,排序完成以关键字序列(265,301,751,129,937,863,742,694,076,438)为例,分别写出执行以下排序算法的各趟排序结束时,关键字序列的状态。(1) 直接插入排序 (2)希尔排序 (3)冒泡排序 (4)快速排序(5) 直接选择排序 (6) 堆排序 (7) 归并排序 (8)基数排序上述方法中,哪些是稳定的排序?哪些是非稳定的排序?对不稳定的排序试举出一个不稳定的实例。答: (1)直接插入排序:(方括号表示无序区)初始态: 265301 751 129 937 863 7
18、42 694 076 438第一趟:265 301751 129 937 863 742 694 076 438第二趟:265 301 751129 937 863 742 694 076 438第三趟:129 265 301 751937 863 742 694 076 438第四趟:129 265 301 751 937863 742 694 076 438第五趟:129 265 301 751 863 937742 694 076 438第六趟:129 265 301 742 751 863 937694 076 438第七趟:129 265 301 694 742 751 863 93
19、7076 438第八趟:076 129 265 301 694 742 751 863 937438第九趟:076 129 265 301 438 694 742 751 863 937(2)希尔排序(增量为5,3,1)初始态: 265 301 751 129 937 863 742 694 076 438第一趟:265 301 694 076 438 863 742 751 129 937第二趟:076 301 129 265 438 694 742 751 863 937第三趟:076 129 265 301 438 694 742 751 863 937(3)冒泡排序(方括号为无序区)初
20、始态 265 301 751 129 937 863 742 694 076 438第一趟: 076 265 301 751 129 937 863 742 694 438第二趟: 076 129 265 301 751 438 937 863 742 694第三趟: 076 129 265 301 438 694 751 937 863 742第四趟: 076 129 265 301 438 694 742 751 937 863第五趟: 076 129 265 301 438 694 742 751 863 937第六趟: 076 129 265 301 438 694 742 751 8
21、63 937(4)快速排序:(方括号表示无序区,层表示对应的递归树的层数)初始态: 265 301 751 129 937 863 742 694 076 438第二层: 076 129 265 751 937 863 742 694 301 438第三层: 076 129 265 438 301 694 742 751 863 937第四层: 076 129 265 301 438 694 742 751 863 937第五层: 076 129 265 301 438 694 742 751 863 937第六层: 076 129 265 301 438 694 742 751 863 93
22、7(5)直接选择排序:(方括号为无序区)初始态 265 301 751 129 937 863 742 694 076 438第一趟: 076 301 751 129 937 863 742 694 265 438第二趟: 076 129 751 301 937 863 742 694 265 438第三趟: 076 129 265 301 937 863 742 694 751 438第四趟: 076 129 265 301 937 863 742 694 751 438第五趟: 076 129 265 301 438 863 742 694 751 937第六趟: 076 129 265
23、301 438 694 742 751 863 937第七趟: 076 129 265 301 438 694 742 751 863 937第八趟: 076 129 265 301 438 694 742 751 937 863第九趟: 076 129 265 301 438 694 742 751 863 937(6)堆排序:(通过画二*树可以一步步得出排序结果)初始态 265 301 751 129 937 863 742 694 076 438建立初始堆: 937 694 863 265 438 751 742 129 075 301第一次排序重建堆:863 694 751 765 4
24、38 301 742 129 075 937第二次排序重建堆:751 694 742 265 438 301 075 129 863 937第三次排序重建堆:742 694 301 265 438 129 075 751 863 937第四次排序重建堆:694 438 301 265 075 129 742 751 863 937第五次排序重建堆:438 265 301 129 075 694 742 751 863 937第六次排序重建堆:301 265 075 129 438 694 742 751 863 937第七次排序重建堆:265 129 075 301 438 694 742 7
25、51 863 937第八次排序重建堆:129 075265 301 438 694 742 751 863 937第九次排序重建堆:075 129 265 301 438 694 742 751 863 937(7)归并排序(为了表示方便,采用自底向上的归并,方括号为有序区)初始态:265 301 751 129 937 863 742 694 076 438第一趟:265 301 129 751 863 937 694 742 076 438第二趟:129 265 301 751 694 742 863 937 076 438第三趟:129 265 301 694 742 751 863 937 076 438第四趟:076 129 265 301 438 694 742 751 863 93
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1