排序专题
今天来总结一下排序相关的各种知识,并且实现:
快速排序:
C++中可以使用std::sort()进行快速排序,但是最好还是要知道其中的原理和实现细节:
代码如下:
void quick_sort(vector<int>&nums,int l,int r){//左指针和右指针
if(l+1>=r){
return;
}
int first=l,last=r-1,key=nums[first];//first指针和last指针、key是正在检查的指针
while(first<last){//当first还没有超过last时
//先调整last指针的值
while(first<last&&nums[last]>=key){//当first不超过last并且大于key时
--last;
}
nums[first]=nums[last];//修改first指针指向的值
//再调整first指针的值
while(first<last&&nums[first]<=key){
++first;
}
nums[last]=nums[first];
}
nums[first]=key;
quick_sort(nums,l,first);
quick_sort(nums,first+1,r);
}
有一个介绍快速排序细节的文章:图解快速排序
实际上中心思想就是先递归地找到其中某一个元素的位置,使用交换的思想,当出现两个大小关系不正确的元素时,将他们进行交换。
里面说的已经相当清楚了,我们来关注时间复杂度:
最差时间复杂度与冒泡排序一致:O(N^2),平均时间复杂度是O(NlogN);
归并排序
归并排序中需要开辟一个临时数组来辅助我们的归并,也就是说比插入排序或者选择排序都要使用更多的存储空间,需要O(n)的额外空间来完成这个排序。只不过现在计算机中时间的效率要比空间的效率重要得多。无论是内存还是硬盘可以存储的数据越来越多,所以设计一个算法,时间复杂度是要优先考虑的。
归并的过程可以用下面这篇文章中的图解法得到:
归并排序图解
其中的过程也是可以使用递归的写法完成的:
void merge_sort(vector<int>&nums,int l,int r,vector<int>&temp){
if(l+1>=r){
return;
}
int m=l+(r-1)/2;//中间数
merge_sort(nums,l,m,temp);
merge_sort(nums,m,r,temp);
int p=l,q=m,i=l;
while(p>m||q<r){
if(q>=r||(p<m&&nums[p]<=nums[q])){
temp[i++]=nums[p++];
}else{
temp[i++]=nums[q++];
}
}
for(i=l;i<r;++i){
nums[i]=temp[i];
}
}
归并排序的时间复杂度:O(NlogN);
空间复杂度:O(N);
插入排序
插入排序的思想是比较简单的,具体思路可以参考这篇文章中的动画:插入排序动画
代码如下:
void insertion_sort(vestor<int> &nums,int n){
for(int i=0;i<n;++i){
for(int j=i;j>0&&nums[j]<nums[j-1];--j){
swap(nums[j],nums[j-1]);
}
}
}
冒泡排序
冒泡排序的整体思路是比较简单的,主要是检查相邻两个元素的大小,当大小关系与位置关系不一致时,就调整两者的位置,代码如下:
void bubble_sort(vector<int> &nums,int n){
bool swapped;
for(int i=1;i<n;++i){
swapped=false;
for(int j=1;j<n-i+1;++j){
if(nums[j]<nums[j-1]){
swap(nums[j],nums[j-1]);
swapped=true;
}
}
if(!swapped){
break;
}
}
}
选择排序
选择排序的思想也是比较简单的,就是从未排好序的部分中选择出最小的数字放在最前面;
代码如下:
void selection_sort(vector<int>&nums,int n){
int mid;
for(int i=0;i<n-1;++i){
mid=i;
for(int j=i+1;j<n;++j){
if(nums[j]<nums[mid]){
mid=j;
}
}
swap(nums[mid],nums[i]);
}
}
以上各个算法的思想细节以及代码都需要牢记,时间复杂度可以参考下图:
以上排序算法的使用方法:
void sort(){
vector<int> nums={1,3,5,7,2,6,4,8,9,2,8,7,6,0,3,5,9,4,1,0};
vector<int> temp(nums.size());
sort(nums.begin(),nums.end());
quick_sort(nums,0,nums.size());
merge_sort(nums,0,nums.size(),temp);
insertion_sort(nums,nums.size());
bubble_sort(nums,nums.size());
selection_sort(nums,nums.size());
}