一、快速排序(Quick'Sort)
01 快速排序的思想
快速排序是一种基于分治法的排序方法,原理是将一个数组分分成两个子数组,其中一个子数
组的所有元素都小于另一个子数组的元素,然后递归地对这两个子数组进行排序。
快速排序的思想是通过不断地将数组分成两个子数组,递归他对子数组进行排序,最终得到
一个有序的数组。这个过程通过选择合适的基准和分区操作来实现。
快速排序拥有更好的时间复杂度O(nlogn),且不需要额外空间。
02快速排序的实现
void QuickSort(int a[],int l,int r){
if(l<r){
int mid=partition(a,l,r); //partition函数定位,进行分组
QuickSort(a,l,mid-1); //分组后继续分治处理
QuickSort(a,mid+1,r);
}
}
int partition(int a[],int l,int r){
int pivot=a[r]; //寻找a[r]在数组中合适的位置
int i=l,j=r;
while(i<j){
while(i<j&&a[i]<=pivot)i++; //将比a[r]大的数和小的数放在一边
while(i<j&&a[j]>=pivot)j--;
if(i<j)swap(a[i],a[j]);
else swap(a[i],a[r]); //i=j;此时i,j指向同一位置,即a[r]应处位置;
}
return i;
}
二、插入排序(insertSort)
01插入排序的思想
插入排序是一种简单直观的排序算法,其基本思想是将待排序的元素逐个插入到已排序序列
的合适位置中,使得已排序序列逐渐扩大,从而逐步构建有月序列,最终得到完全有序的序
列。
它类似于我们打扑克牌时的排序方式,将一张张牌插入到已经有序的手牌中。
时间复杂度为O(n^2)。
02插入排序的实现
for(int i=2;i<=n;i++){
//此时[1,i-1]为已排序的有序数列
int val=a[i],j;
//从a[i]开始继续插入,j用于存放a[i]正确的位置;
for(j=i;j>0&&a[j-1]>val;j--)
a[j]=a[j-1];
//将大于a[i]的向后挪一位
a[j]=val;
//将a[i]插入
}
三、选择排序(select Sort)
01选择排序的思想
选择排序的思想和冒泡排序类似,是每次找出最大的然后直接接放到右边对应位置,然后将最
右边这个确定下来(而不是一个一个地交换过去)。
再来确定第二大的,再确定第三大的....
对于数组a[,具体的来说,每次确定操作(假设当前要确定的是i位置)就是从左往右扫描,
计算出最大元素的下标max_id,最后执行一次swap(a[max_id],a[i])将路两项交换即可
第一次确定操作是将a[1]~a[n]中最大的放到a[n];
第二次确定操作是将a[1]~a[n-1]中最大的放到a[n-1]。
类推(类似地,如果你想先把最小的放到左边也是可以的),时间复杂度为0(n^2)
02选择排序的实现
//对a[n]数组进行选择排序;
for(int i=n;i>0;i--){
int max_id=1;
for(int j=1;j<=i;j++){
if(a[j]>a[max_id])max_id=j; //找出最大数的位置
}
swap(a[max_id],a[i]);
}
四、归并排序(mergeSort)
01归并排序的思想
归并排序和快速排序类似,也是一种基于分治法的排序方法。
原理是将一个数组分成两个子数组,将子数组向下递归的排用序后(当数组中仅有一个元素值
无需再排序了,直接返回),得到两个有序数组,然后进行0(n)的名合并,最终合并成有序的原数组。
快速排序拥有较好的时间复杂度O(nlogn),但需要额外的空间用于合并数组。
02归并排序的实现
void MergeSort(int a[],int l,int r){
if(l==r)return; //当区间长度为1时,排序结束;
int mid=(l+r)/2; //将数组分治
MergeSort(a,l,mid);
MergeSort(a,mid+1,r);
//得到了两端有序的数组a[l]-a[mid]和a[mid+1]-a[r]
int pl=l,pr=mid+1,pb=1;
//pl为左段的下标,pr为右段的下标,pb为数组b[]的下标,b[]为辅助的数组;
while(pl<=mid||pr<=r){
if(pl>mid) //左段已经放完,直接将右段放入
b[pb++]=a[pr++];
else if(pr>r) //右段已经放完,直接将左段放入
b[pb++]=a[pl++];
else{
if(a[pl]>a[pr])b[pb++]=a[pr++]; //取小放入
else b[pb++]=a[pl++];
}
}
for(int i=1;i<=n;i++)a[i]=b[i];
}