归并排序法
参考[博主dreamcatcher-cx的博客](https://www.cnblogs.com/chengxiao/p/6194356.html)
归并排序法,总结的来说是将无序数列不断二分,最终分为单个元素,然后再回到上一级,依据已有顺序再进行排序。时间复杂度最高期望和平均期望均为O(nlogN),是十分稳定的排序方法。
8🔒废话了,浅谈一下我的理解
原有无序数组 8,4,5,7,1,3,6,2,不断从中点二分,得到8个元素
划分结束,排序环节:
依照第二次划分,将三次划分的结果8、4分为一组,5、7分为一组,1、3一组,6、2一组。
8>4,所以4在前,8在后,这个很好理解,同理得到其他结果:4,8| 5,7| 1,3| 2,6。
依照第一次划分,数字48和57为一组进行排序,数字13和26为一组。
以4,8,5,7组为例
- 4与5比较,4<5,4排第一位,右组由于已经排序好,后面的数必定没有前面的大,所以第二位只会在左组第二位和右组第一位中出现,所以左边的组数字往后移动一个,到了8
- 8与5比较,5<8,所以5排第二位,右组往后移动一位,到了7。
- 7与8比较,7<8,7排在第三位,8排在第四位,排序完成。
通过以上的排序得到了有序数组(4578),再同理又可根据(1,3,2,6)得到有序数组(1,2,3,6)。
最后,继续依据这种比较方法,得到排序完成后的有序数组(1,2,3,4,5,6,7,8)。
不难发现,以上的操作,无论是二分,还是排序,重复的地方太多了,我们完全可以使用递归调用的方法,让函数自我调用来实现上述操作,
归并排序法本质上都是将两个数组合并成一个数组,两边数组的下标,在排序过程中分别开始移动,仅仅在原有数组的基础上通过用temp保存变量,来进行这种操作,显然太吃力了(要附的值太多了!)所以一般需要一个数组temp用来临时存放数值,等到每次排序完成,再赋给原有数组
理论部分结束,上代码
void mergeSort(int *a,int left,int right) {//*a 代表着函数的地址,
//left左边需要开始排序的下标,right右边结束排序的下标
if(left==right)//递归调用需要此结束条件!否则就死循环了!
return ;
int mid=left+right>>1;//双目运算符>>,原常数的二进制数往>>右边移动
//>>1的意思和除以2一样
mergeSort(a,left,mid);//分别从自身左边、右边开始递归
mergeSort(a,mid+1,right);
for(int i/*记录数组b的下标*/= left,j/*左边的下标*/ = left,k /*右边的下标*/= mid+1; i<= right; i++) {
if(j>mid) {
b[i]=a[k++];//全局变量整型数组b[i],替身使者罢了
continue;//这个地方是判断左右是否有一边已经比较结束,一边结束另一边全部赋值即可
}
if(k>right) {
b[i]=a[j++];
continue;
}
b[i]=a[j]<a[k]?a[j++]:a[k++];//从j和k里面挑个大的
}
for(int i=left; i<right; i++)
a[i]=b[i];//还给a数组
}
快速排序算法
选择一个数作为比较的基准,(得把它存起来),比它大的数不管三七二十一,全放在后面,比它小的数就放在前面。完成之后,再对基准前后两部分执行相同的步骤,直到无法执行为止(起始数>=终止数)
听起来蛮好理解的,这里我尝试用较为简介的代码实现:
void quick_sort(int *a,int begin,int end) {
if(begin<end) {
int temp=a[begin];
int left=begin,right=end;
while(left<right) {
//找一个不合规则的数
while(left<right&&a[right]>temp)
right--;
//放在合规则的地方
a[left]=a[right];
//以下同理
while(left<right&&a[left]<=temp)
left++;
a[right]=a[left];
}
a[right]=temp;
quick_sort(a,begin,left-1),quick_sort(a, left+1,end);
} else return;
}
简洁、逻辑明确、复杂度低,快速排序法真是天才般的算法!
sort函数
懒人福音😅
用sort函数需要调用algorithm库。(这个应该属于STL部分了吧)
直接调用
sort(数组名+a1,数组名+a2);
直接调用的话,默认排成从小到大的序列
加一点规则greater<(类型)T>()
sort(数组名+a1,数组名+a2,greater<T(T表示的是前面数组的类型)>())
从大到小调用
自由使用
先定义个排序规则