前言
在之前的博客中,我讲解了关于快速排序实现的两种方法:Hoare法与挖坑法,今天来说一说第三种方法——前后指针法,这种方法主要也是找出基准数,放到序列的中间位置后采用递归进行分割序列,最终得出有序序列。
目录
前后指针法的主要思想:
通过创建两个指针,prev指针指向数组序列首元素位置,cur指向prev的下一个位置,cur通过遍历去寻找比key基准值小的,若找到了,还得看prev的下一个位置是否为cur所处的位置,若prev的下一个位置确实为cur所处位置,则将cur指向的值与prev指向的值进行互换,若prev的下一个位置不是cur所处位置,则cur继续往后遍历,直到cur遍历结束,最后要将key基准值与prev指向的值进行互换,最终确认基准值处于数组序列的中间位置。
图解:
代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
# include<stdio.h>
//前后指针法
//打印
void PrintArr(int* arr, int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
//交换函数
void Swap(int* p1, int* p2) {
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
//三数取中
int GetMidIndex(int* arr, int left, int right) {
int mid = (right - left) / 2 + left;
if (arr[left] < arr[mid]) {
if (arr[mid] < arr[right]) {
return mid;
}
else if (arr[left] > arr[right]) {
return left;
}
else {
return right;
}
}
else { //arr[left]>=arr[mid]
if (arr[mid] > arr[right]) {
return mid;
}
else if (arr[left] < arr[right]) {
return left;
}
else {
return right;
}
}
}
//前后指针法
int PartSort(int* arr, int left, int right) {
int mid = GetMidIndex(arr, left, right);
Swap(&arr[left], &arr[mid]);
int keyi = left; //基准值下标放在最左侧
int prev = left;
int cur = left + 1;
while (cur<=right) {
if (arr[cur] < arr[keyi] && ++prev != cur) {
Swap(&arr[prev], &arr[cur]);
}
++cur;
}
Swap(&arr[keyi], &arr[prev]); //prev已经走到了中间,Swap一下,基准值就从数组最左侧转到了中间了
return prev;
}
//递归快排
void QuickSort(int* arr, int begin, int end) {
if (begin >= end) {
return;
}
int keyi = PartSort(arr, begin, end);
QuickSort(arr, begin, keyi - 1);
QuickSort(arr, keyi + 1, end);
}