8种排序算法Ultimate.docx
- 文档编号:8634919
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:11
- 大小:19.15KB
8种排序算法Ultimate.docx
《8种排序算法Ultimate.docx》由会员分享,可在线阅读,更多相关《8种排序算法Ultimate.docx(11页珍藏版)》请在冰豆网上搜索。
8种排序算法Ultimate
8种排序算法(有代码)
个人对这8种排序算法的理解,希望对大家有点帮助.
趁自修时间,自己将这8种排序的代码写了一下.......
1.简单的选择排序
boolselectionsort(int*array,intn) //array为存储数据的数组,n为数组元素个数
{
intk,temp; //k用来存储,临时最小数据的位置
for(inti=0;i { k=i; for(intj=i+1;j if(array[j] k=j; if(k! =i) //若最小数,不为array[i],则array[i]与array[k]进行交换 { temp=array[i]; array[i]=array[k]; array[k]=temp; } } returntrue; } 思想: 逐个找出,第一小,第二小....第n小的数... 算法平均时间复杂度: O(n^2) 2.插入排序 boolinsertionsort(int*array,intn) { inttemp; //用来存储,插入的数据 for(inti=1;i { temp=array[i]; //用temp记录array[i] for(intj=i-1;j>=0;j--) //逐个向前寻找插入点 { if(temp>array[j]) //找到,跳出循环 break; else //没找到,将前一个数据后移 array[j+1]=array[j]; } array[j+1]=temp; } returntrue; } 思想: 逐个取数,插入一个有序数组(从后向前插) 算法平均时间复杂度: O(n^2) 3.自底向上排序 boolbottomupsort(int*array,intn) { intlength=1,temp_length,i; //temp_length表示单个合并数组的长度 while(length { 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); //合并i~i+temp_length-1和i+temp_length~i+length-1段 i=i+length; //取下一个合并段的起始位置 } if(i+temp_length merge(array,i,i+temp_length,n-1); //对尾部剩余段合并 } returntrue; } boolmerge(int*array,intstart1,intstart2,intn) //合并两个有序数组 { inttemp_n=n-start1+1, //两合并数组的长度和 *temp_array, n1=start2-1, //第一个有序数组的末端位置 temp_start1=start1; //记录start1的初始位置 temp_array=(int*)malloc(sizeof(int)*temp_n); //申请长度为temp_n的整形空间,用于临时存储合并后的数组 for(inti=0;start1<=n1&&start2<=n;i++) //对两个有序数组进行合并,存储于temp_array { if(array[start1]<=array[start2]) { temp_array[i]=array[start1]; start1++; } else { temp_array[i]=array[start2]; start2++; } } if(start1<=n1) { while(start1<=n1) { temp_array[i++]=array[start1]; start1++; } } else { while(start2<=n) { temp_array[i++]=array[start2]; start2++; } } for(i=0,start1=temp_start1;i { array[start1]=temp_array[i]; } free(temp_array); returntrue; } 思想: 将数组的个部分,两两有序数组进行合并 算法平均时间复杂度: O(nlogn) 4.快速排序 voidQuickSort(intlow,inthigh,int*array) { intpos; if(low { pos=SPLIT(low,high,array); //以array[low]进行划分,pos最为划分点 //前一部分 QuickSort(low,pos-1,array); //对划分后的前一部分递归处理 QuickSort(pos+1,high,array); //对划分后的后一部分递归处理 } } intSPLIT(intlow,inthigh,int*array) { inttemp=array[low]; //用temp来记录划分数 while(low { while(array[high]>temp&&low high--; if(low==high) break; else { array[low]=array[high]; low++; } while(array[low] low++; if(low==high) break; else { array[high]=array[low]; high--; } } array[low]=temp; //最终low=high作为划分点,并将划分数存于array[low] returnlow; } 思想: 就是你从数组中任取一个元素p(可随机取,现在以取第一个为例) 以P作为主元,对数组进行划分,前一部分小于P,后一部分大于p 最后划分处存储p 然后分别对划分后的前一部分和后一部分递归调用 算法平均时间复杂度: O(nlogn) 5.归并排序 boolMergeSort(intlow,inthigh,int*array) { intmiddle=(high+low)/2; //将数组划分为2分 if(low { MergeSort(low,middle,array); //对前一部分进行递归处理 MergeSort(middle+1,high,array); //对后一部分进行递归处理 HeBing(low,middle,middle+1,high,array);//将排序后的,前后两部分,进行合并 } returntrue; } boolHeBing(intlow1,inthigh1,intlow2,inthigh2,int*array) { int*temp, i=low1, j=low2, k=0; temp=(int*)malloc((high2-low1+1)*sizeof(int)); //temp用于临时存储合并后的数组 while(i<=high1&&j<=high2) //对两个有序数组进行合并 { if(array[i] { temp[k++]=array[i]; i++; } else { temp[k++]=array[j]; j++; } } if(i<=high1) { while(i<=high1) temp[k++]=array[i++]; } else { while(j<=high2) temp[k++]=array[j++]; } for(i=low1,j=0;i<=high2;i++,j++) //将合并后的数组,复制到array中 { array[i]=temp[j]; } free(temp); returntrue; } 思想: 将数组划分为小数组,通过局部的有序合并,解决问题 算法平均时间复杂度: O(nlogn) 6.冒泡排序 boolbubblesort(int*array,intn) { intflag=1, //用来标记是否发生交换 temp; for(inti=0;i { for(intj=i+1;j { if(array[j] { temp=array[i]; array[i]=array[j]; array[j]=temp; flag=0; } } if(flag) //如果flag为真,及没发生交换,直接跳出循环 break; else flag=1; } returntrue; } 思想: 相邻两数比较,小数放前面 算法平均时间复杂度: O(n^2) 7.堆排序 boolslipdown(int*array,intcur,int n) { for(intnext=2*cur;next<=n;next=2*cur) //next表示cur的左孩子 { if(next next++; if(array[next] break; inttemp=array[cur]; //交换cur和他孩子中的大者 array[cur]=array[next]; array[next]=temp; cur=next; //令当前需要调整的关键字的位置cur=next } returntrue; } boolheapsort(int*array,intn) { inttemp; for(inti=n/2;i>0;i--) //将数组调整为大顶堆 slipdown(array,i,n); for(intN=n;N>1;N--) //选出堆中最大元,存于N位置,循环进行 { temp=array[N]; array[N]=array[1]; array[1]=temp; slipdown(array,1,N-1); } returntrue; } 思想: 用二叉树的结构来表示数组,及用数组来表示二叉树的结构,比如i为父节点其孩子为,2i,和2i+1 其中,大顶堆中父节点大于其两个孩子 算法平均时间复杂度: O(nlogn) 8.基数排序 boolradixsort(int*array,intn) { LTENL[10]; //其中TENL[m].number中存储,数据的第i位为m的数据 intk; for(inti=0;i<10;i++) TENL[i].n=0; for(i=1;i<=5;i++) //这里假设数据都小于100000,对数据进行五次分配 { for(intj=0;j { k=getnum(array[j],i); TENL[k].number[TENL[k].n]=array[j]; TENL[k].n++; } j=0; for(k=0;k<10;k++) //将此次分配后的数据,按顺序重新置入array中 { for(intm=0;m array[j++]=TENL[k].number[m]; TENL[k].n=0; } } returntrue; } int getnum(intnum,inti) //从个位起,获得num的第i为数据 { inttemp=1; for(intj=0;j temp=temp*10; return(num%temp-num%(temp/10))/(temp/10); } 思想: 先从数据的低位开始,进行分配,分成10个空间,分别存储位为,0,1,2,3...9 重复的对次地位操作,知道预定的高位,排序完成 8种排序算法 个人对这8种排序算法的理解,希望对大家有点帮助. 趁自修时间,自己将这8种排序的代码写了一下....... 1.简单的选择排序 思想: 逐个找出,第一小,第二小....第n小的数... 算法平均时间复杂度: O(n^2) 2.插入排序 思想: 逐个取数,插入一个有序数组(从后向前插) 算法平均时间复杂度: O(n^2) 3.自底向上排序 思想: 将数组的个部分,两两有序数组进行合并 算法平均时间复杂度: O(nlogn) 4.快速排序 思想: 就是你从数组中任取一个元素p(可随机取,现在以取第一个为例) 以P作为主元,对数组进行划分,前一部分小于P,后一部分大于p 最后划分处存储p 然后分别对划分后的前一部分和后一部分递归调用 算法平均时间复杂度: O(nlogn) 5.归并排序 思想: 将数组划分为小数组,通过局部的有序合并,解决问题 算法平均时间复杂度: O(nlogn) 6.冒泡排序 思想: 相邻两数比较,小数放前面 算法平均时间复杂度: O(n^2) 7.堆排序 思想: 用二叉树的结构来表示数组,及用数组来表示二叉树的结构,比如i为父节点其孩子为,2i,和2i+1 其中,大顶堆中父节点大于其两个孩子 算法平均时间复杂度: O(nlogn) 8.基数排序 思想: 先从数据的低位开始,进行分配,分成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)直接插入排序: (方括号表示无序区) 初始态: 265[301751129937863742694076438] 第一趟: 265301[751129937863742694076438] 第二趟: 265301751[129937863742694076438] 第三趟: 129265301751[937863742694076438] 第四趟: 129265301751937[863742694076438] 第五趟: 129265301751863937[742694076438] 第六趟: 129265301742751863937[694076438] 第七趟: 129265301694742751863937[076438] 第八趟: 076129265301694742751863937[438] 第九趟: 076129265301438694742751863937 (2)希尔排序(增量为5,3,1) 初始态: 265301751129937863742694076438 第一趟: 265301694076438863742751129937 第二趟: 076301129265438694742751863937 第三趟: 076129265301438694742751863937 (3)冒泡排序(方括号为无序区) 初始态[265301751129937863742694076438] 第一趟: 076[265301751129937863742694438] 第二趟: 076129[265301751438937863742694] 第三趟: 076129265[301438694751937863742] 第四趟: 076129265301[438694742751937863] 第五趟: 076129265301438[694742751863937] 第六趟: 076129265301438694742751863937 (4)快速排序: (方括号表示无序区,层表示对应的递归树的层数) 初始态: [265301751129937863742694076438] 第二层: [076129]265[751937863742694301438] 第三层: 076[129]265[438301694742]751[863937] 第四层: 076129265[301]438[694742]751863[937] 第五层: 076129265301438694[742]751863937 第六层: 076129265301438694742751863937 (5)直接选择排序: (方括号为无序区) 初始态 [265301751129937863742694076438] 第一趟: 076[301751129937863742694265438] 第二趟: 076129[751301937863742694265438] 第三趟: 076129265[301937863742694751438] 第四趟: 076129265301[937863742694751438] 第五趟: 076129265301438[863742694751937] 第六趟: 076129265301438694[742751863937] 第七趟: 076129265301438694742[751863937] 第八趟: 076129265301438694742751[937863] 第九趟: 076129265301438694742751863937 (6)堆排序: (通过画二*树可以一步步得出排序结果) 初始态 [265301751129937863742694076438] 建立初始堆: [937694863265438751742129075301] 第一次排序重建堆: [863694751765438301742129075]937 第二次排序重建堆: [751694742265438301075129]863937 第三次排序重建堆: [742694301265438129075]751863937 第四次排序重建堆: [694438301265075129]742751863937 第五次排序重建堆: [438265301129075]694742751863937 第六次排序重建堆: [301265075129]438694742751863937 第七次排序重建堆: [265129075]301438694742751863937 第八次排序重建堆: [129075]265301438694742751863937 第九次排序重建堆: 075129265301438694742751863937 (7)归并排序(为了表示方便,采用自底向上的归并,方括号为有序区) 初始态: [265][301][751][129][937][863][742][694][076][438] 第一趟: [265301][129751][863937][694742][076438] 第二趟: [129265301751][694742863937][076438] 第三趟: [129265301694742751863937][076438] 第四趟: [07612926530143869474275186393
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 排序 算法 Ultimate