直接插入排序首先,我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始排序范围只有一个元素,即数组的第一个元素。插入算法的核心思想是取未排序区间内的元素,在已排序区间内找到合适的插入位置插入,保证已排序区间内的数据始终有序。重复这个过程,直到未排序区间内的元素为空,算法结束。如图所示,需要排序的数据为4,5,6,1,3,2,其中左边是已排序的范围,右边是未排序的范围。插入排序包括两个操作,一个是元素的比较,一个是元素的移动。例如,当我们需要向排序区间[1,4,5,6]中插入一个数据3时,我们需要将3的大小依次与排序区间的元素6,5,4,1进行比较找到合适的插入位置。找到插入点后,我们还需要将插入点之后的元素顺序往后移一位,为要插入的元素3腾出空间。比如比较3和6的时候,此时可以交换3和6的位置,以此类推,3和5交换,3和4交换。当3和1比较的时候发现3大于1,不需要交换。完成了3的插入过程。C代码include//升序排序voidInsertSort(int*p,intsz){for(inti=0;i=0){if(p[end+1]>1;//移位效率有点高比除以2更有效//leftmidrightif(a[left]a[right]){向左返回;}else{向右返回;}}else//a[left]>=a[mid]{if(a[mid]>a[right]){returnmid;}elseif(a[left]=a[keyi])--对;//查找bigwhile(left=key){--right;}//放在左边坑的位置,右边形成一个新的坑a[left]=a[right];//找到大while(left=end)//[begin,end]区间为0或区间不存在,returnreturn;//1.如果子区间有很多数据,继续单遍选择key,划分子区间递归分治//2.如果数据inthissub-intervalissmall,divideandconquerandrecursivelyisnotcost-effectively//这时候越往后递归,子区间越多,每个子区间的数据越少,它在每个子区间递归是不划算的,//后面可以进行插入排序,因为此时每个子区间都接近有序,接近于山排序if(end-begin>0)//小区间优化的效果不是很明显。如果有针对性的调整相应的数据层级//数据量越大,比如把20换成1000的效果很明显20是官方给的,官方不敢给太大{intkeyi=PartSort1(a,begin,end);//intkeyi=PartSort2(a,begin,end);//intkeyi=PartSort3(a,begin,end);//[begin,keyi-1]keyi[keyi+1,end]QuickSort(a,begin,keyi-1);//递归QuickSort(a,keyi+1,end);//recursion}else{InsertSort(a+开始,结束-开始+1);//HeapSort(a+begin,end-begin+1);也可以换成堆排序,希尔排序效果会更好}}时间复杂度:O(N*logN)空间复杂度:O(logN)稳定性:不稳定合并排序合并排序(MERGE-SORT)是一种基于合并操作的有效排序算法,它是一种分而治之的方法(DivideandConquer),一个非常典型的应用是将有序的子序列合并为获得一个完全有序的序列;即先对每个子序列进行排序,再对子序列段进行排序。将两个排序列表合并为一个排序列表称为双向合并。void_MergeSort(inta,intleft,intright,inttmp){if(left>=right)return;intmid=(left+right)>>1;//[left,mid][mid+1,right]_MergeSort(a,left,mid,tmp);//先递归分治_MergeSort(a,mid+1,right,tmp);//将两个有序的子区间合并到tmp中,并复制回去intbegin1=left,end1=mid;intbegin2=mid+1,end2=right;inti=left;while(begin1<=end1&&begin2<=end2){if(a[begin1]max)max=a[i];}intrange=max-min+1;//min和max之间的自然数个数(包括min和max本身)int*count=(int*)calloc(range,sizeof(int));//开辟存储整个range类型的内存空间,并将内存空间设置为0if(count==NULL){printf("mallocfail\n");exit(-1);}//统计相同元素出现的次数(相对映射)for(inti=0;i