书接上回,我们继续介绍排序算法。
笔者的编程环境:
- 语言:c++
- 编译器: Code Blocks
- 系统环境:window 10 x64
排序算法
快速排序
基本思想
- 在待排序数组中任选一个元素作为枢轴pivot(也有叫基准base的)
- 一趟排序使得元素组划分成两部分,一部分元素均大于枢轴,一部分均小于枢轴。
- 对划分后的两部分继续执行第一步与第二部,至序列有序
空间复杂度:O(logn)
时间复杂度:O(nlogn)
稳定性:不稳定
代码如下:
template<typename T>
int partition(T arr[],int low,int high)//划分
{
T index=arr[low];
while(low<high){
while(low<high&&arr[high]>=index)high--;
arr[low]=arr[high];
while(low<high&&arr[low]<=index)low++;
arr[high]=arr[low];
}
arr[low]=index;
return low;
}
template<typename T>
int quickSort(T arr[],int low,int high)//排序
{
if(low<high){
int index=partition(arr,low,high);
quickSort(arr,low,index-1);
quickSort(arr,index+1,high);
}
return 0;
}
template<typename T>
int sort(T arr[],int count)//排序入口
{
quickSort(arr,0,count-1);
return 0;
}
堆排序
基本思想
- 将待排序序列构建成堆(以大根堆为例)
- 将对顶元素与堆中最后一个元素交换,并将最后一个元素脱离堆
- 对剩下的元素进行堆调整,使其依然是大根堆。
- 重复执行2,3步至堆消失
空间复杂度:O(1)
时间复杂度:O(nlogn)
稳定性:不稳定
代码如下:
template<typename T>
int swap(T *a,T *b)//交换函数
{
T c;
c=*a;
*a=*b;
*b=c;
return 0;
}
template<typename T>
int buildHeap(T arr[],int count)//建堆函数
{
for(int i=count/2-1;i>=0;i--)
{
heapAdjust(arr,count,i);
}
return 0;
}
template<typename T>
int heapAdjust(T arr[],int count,int begin)//堆调整函数
{
T index=arr[begin];
for(int i=begin*2;i<count;i*=2)
{
if(i<count-1&&arr[i]<arr[i+1])i++;
if(index>=arr[i])break;
else{
arr[begin]=arr[i];
begin=i;
}
}
arr[begin]=index;
return 0;
}
template<typename T>
int sort(T arr[],int count)//堆排序
{
buildHeap(arr,count);
for(int i=count-1;i>0;i--)
{
swap(arr[i],arr[0]);
heapAdjust(arr,i,0);//通过不断调整堆的大小使最后一个元素脱离堆
}
return 0;
}
归并排序(二路归并)
基本思想
- 将待排序序列划分成n个组
- 将得到的组两两合并得到一定数量的有序组
- 重复执行第二步至仅剩一个有序组
示意图如下:
空间复杂度:O(n)
时间复杂度:O(nlogn)
稳定性:稳定
代码如下:
//需要提前准备一个与待排序数组同类型同长度的数组temp
//最终结果在原待排序数组中
template<typename T>
int sort(T arr[],int count,T temp[])//排序入口
{
mergeSort(arr,0,count-1,temp);
return 0;
}
template<typename T>
int mergeSort(T arr[],int low,int high,T temp[])//划分
{
if(low<high)
{
int mid=(low+high)/2;
mergeSort(arr,low,mid,temp);
mergeSort(arr,mid+1,high,temp);
merge(arr,low,mid,high,temp);
}
return 0;
}
template<typename T>
int merge(T arr[],int low,int mid,int high,T temp[])//合并
{
for(int k=low; k<=high; k++)temp[k]=arr[k];
int i=low,j=mid+1,k=low;
for(; i<=mid&&j<=high; k++)arr[k]=temp[temp[i]<=temp[j]?i++:j++];
while(i<=mid)arr[k++]=temp[i++];
while(j<=high)arr[k++]=temp[j++];
return 0;
}