目录
快速排序(Quick Sort)简介:
整体思想,每次都取最左边的数据作为基准值,循环一次后,将基准值放入中间位,即 i == j的位置。此时,基准值在中间,左边都是比基准小的数,右边都是比基准大的数,
之后分别让基准值左边的数据和右边的数据继续执行快速排序,
直到最后i-1 < start , i+1 > end,
即左边基准值处于数组首位或者第二位,右边的基准值处于数组的末位或末尾的前一位
算法描述:
设置两个变量 start、end,排序开始时:通过调用函数传参,start = 0,end = size-1。
1. 在整个数组找到基准值的位置,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面
默认数组的第一个数为基准数据,赋值给norm,即norm=arr[start]。
因为默认数组的第一个数为基准,所以从后面开始向前搜索(end--),找到第一个小于norm的arr[end],就将 array[end] 赋给 array[strat],(循环条件是 array[end] >= norm)
此时再从前面开始向后搜索(start++),找到第一个大于norm的array[start],就array[start] 赋给 array[end],(循环条件是 array[start] <= norm)
循环执行此步骤,直到 start=end,该位置就是基准位置。此时把基准数据赋给当前位置。
2.第一次循环找到的基准位置,分别用作为下一趟的分界点,start-1 和 start+1;
3.递归调用分界点前和分界点后的子数组排序,重复第一步;
4.最终就会得到排序好的数组。
动图演示:
代码实现:
#include <stdio.h>
#define N 10
/*
快排函数
整体思想,每次都取最左边的数据作为基准值,循环一次后,
将基准值放入中间位,即 i == j的位置。
此时,基准值在中间,左边都是比基准小的数,右边都是比基准大的数,
之后分别让基准值左边的数据和右边的数据继续执行快速排序,
直到最后i-1 < start, i+1 > end,
即左边基准值处于数组首位或者第二位,右边的基准值处于数组的末位或末尾的前一位
*/
void Qucick_sort(int *arr, int start ,int end) {
int i = start; //i指向数组首位
int j = end; //j指向数组末位
int norm = arr[i]; //设置一个基准值,每次都取数组首位作为基准值
while(i < j) { //进行第一轮排序,停止的条件是i == j
while(i < j && norm <= arr[j]) { //拿基准值与末位和其之前的数据循环比较
j--;
}
arr[i] = arr[j]; //如果有比基准值小的值,跳出循环,进行数据交换
//再将基准值与左边的数据进行比较
while(i < j && norm >= arr[i]) {
i++;
}
arr[j] = arr[i];
}
//第一次循环执行完毕后,将基准值放入中间位,即 i == j的位置
arr[i] = norm;
//比较第一次基准值左边的所有数据,递归执行快排函数即可
if(i-1 > start) {
Qucick_sort(arr,start,i-1);
}
//比较第一次基准值右边的所有数据,递归执行快排函数即可
if(i+1 < end) {
Qucick_sort(arr,i+1,end);
}
return;
}
int main(int argc, const char *argv[])
{
int arr[N] = {55, 24, 45, 15, 96, 23, 36, 76, 36, 0};
int i;
printf("排序前\n");
for(i = 0;i < sizeof(arr)/sizeof(arr[0]);i++) {
printf("%d ",arr[i]);
}
putchar(10);
//调用快速排序函数,传递想要排序的数组和起始下标
Qucick_sort(arr, 0, N-1);//数组最后一位的下标是 N-1
printf("排序后\n");
for(i = 0;i < sizeof(arr)/sizeof(arr[0]);i++) {
printf("%d ",arr[i]);
}
putchar(10);
return 0;
}