小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前言
每天一小步,成功一大步。大家好,我是程序猿小白 GW_gw,很高兴能和大家一起学习每天小知识。
以下内容部分来自于网络,如有侵权,请联系我删除,本文仅用于学习交流,不用作任何商业用途。
摘要
本文主要讲诉快速排序的主要思想和具体实现。
1. 主要思想
快速排序是一种交换排序。时间复杂度平均情况是O(Nlog2N),最坏情况是O(N*2),最好情况是O(Nlog2N)。是一种不稳定的排序。
主要思想:分治法。
确定基准元素,把元素分为两部分,一部分小于基准元素,一部分大于基准元素。再把分的两部分继续分为四部分,直到每部分只有一个元素为止。
上图是以最后一个为基准元素。
每次返回基准元素的位置,进行下一次分治。
2. 具体实现
这里给出两种实现方法。
2.1 双指针法
主要思想:
- 设置两个指针front,rear ,并确定一个基准元素 。
- front从前面找比基准元素大的。
- rear 从后往前找,比基准元素小的。
- 交换fornt和rear的值,并把fornt,rear前进一位。
- fornt和rear相遇时,结束寻找。
- 最后交换基准元素和相遇位置。
void qsort1(int arr[],int left,int right){
if(left < right){
int fornt = left;
int rear = right;
int key = arr[right];
while(fornt < rear){
//需要一直注意fornt小于rear
while(fornt < rear && arr[fornt] < key)
fornt++;
while(fornt < rear && arr[rear] >= key)
rear--;
if(fornt < rear){
swap(&arr[fornt],&arr[rear]);
}
}
//如果最后一个是最大的就没必要交换。
if(rear != right){
swap(&arr[fornt],&arr[right]);
}
qsort1(arr,left,fornt-1);
qsort1(arr,fornt+1,right);
}
}
2.2 设置大区法
- 设置一个大区保存比基准大的元素,记录大区的最小下标。
- 从前往后找,遇到比基准元素小的元素,就和大区的最小下标的元素进行交换,把大区的最小下标+1。
- 最后把大区最小下标对应的元素和基准元素进行交换 。
void qsort2(int arr[],int left,int right){
if(left < right){
int down = left;
int p = left;
int key = arr[right];
while(p < right){
if(arr[p] < key){//基准元素最大没必要交换
if(p != down)
swap(&arr[p],&arr[down]);
down++;
}
p++;
}
if(down != right){//如果基准元素最大也没必要交换
swap(&arr[down],&arr[right]);
}
if(down - left > 1)
qsort2(arr,left,down-1);
if(right - down > 1)
qsort2(arr,down+1,right);
}
}
结语
以上就是我对快速排序的一些浅见,希望对读者有所帮助,如有不正之处,欢迎掘友们批评指正。