快速排序:
一个小人往后走,一个小人往前走。后面的小人先出发,因为最后定点位置需要与第一个元素交换,所以一定要比第一个元素小,所以后面的小人先走(单从此图出发)
共有两种解法:(哪边为key另一边先走)
左边为key,右边先走(最后定住的值一定小于key),相遇值比key小
右边为key,左边先走(最后定住的值一定大于key),相遇值比key大
临界条件理解:left<right
当递归进入下一轮时,由于left始终停在比key小的位置,所以在right- -的过程中,当遇到left此时一定会停下,此时left=right,退出循环(就上图而言)
当left=right
将key的位置与right交换,返回right(key的位置),接着进行递归,下一次递归时,将数组缩小了一半,且不包含key
以下为代码实现
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partsort(int* a, int left, int right) {
int key = left;
while (left < right) {
while (left < right && a[right] >= a[key]) {
//为了防止左边与右边与key相同时就停止,之后两个交换后,right不再--,left不再++,
//使得死循环,这里再判断与key的大小关系时,右边比key大于等于的就继续前进,
//左边小于等于继续前进
right--;
}
while (a[left] <= a[key]&&left<right) {
left++;
}
swap(&a[left], &a[right]);
}
swap(&a[right], &a[key]);
return right;
}
void quicksort(int* a, int left,int right) {
if (left >= right) {
return;
}
int mid=partsort(a, left, right);
quicksort(a, left, mid - 1);//情况:左边加上mid剩下两个元素,不用排序,返回,此时left=right
quicksort(a, mid + 1,right );
}
void main() {
int a[] = {33,55,66,32,41,2,7,97,53,62,12};
int right = sizeof(a) / sizeof(a[0]);
quicksort(a, 0, right-1);
for (int i = 0; i < right; i++) {
printf("%d ", *(a+i));
}
printf("\n");
}