参考:https://wiki.jikexueyuan.com/project/easy-learn-algorithm/fast-sort.html
基本思想:
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
方法:
在冒泡排序的基础上采用分治和递归的思想;
步骤:
- 选一个temp元素(随意选择)
- 小于tmp放左边, 大于tmp放右边
- 对左半边,重复进行以上两步骤
- 对右半边,重复进行以上两步骤
- 递归直到半区内只有一个元素的时候返回
时间复杂度:
解析:
int * a = {10, 8, 5, 21, 4 ,9 , 6}; temp = 6; // 将temp设置为最右边元素 i = 10; // i为最左边的元素 j = 9; // j为最右边的元素 不包括temp j - - 大于temp的数分为一组, i + + 小于temp的数分为一组
第一轮:
i++ 10 不小于 6 i=0
j-- 9 大于 6 j-- 4 不大于 6 j=5
10 < 4? 互换位置
4,8,5,21, 10, 9, 6
4 < 6? 不换位置
第一轮结果:4,8,5,21, 10, 9, 6
第二轮:
i++ 8 不小于 6 i=1
j-- 21 大于 6 j-- 5 不大于 6 j=2
8 > 5 ? 互换位置
4,5,8,21, 10, 9, 6
8 < 6 ? 互换位置
第二轮结果: 4,5,6,21, 10, 9, 8
完整代码
#include <stdio.h> void PrintSort(int * a, int n) { int i; for (i=0; i<n; i++) { printf("%d ", a[i]); } printf(" "); } void swap(int * a, int *b ) { int t = *a; *a = *b; *b = t; } int partition(int * a, int low, int high) { int i = low - 1; // low - 1 因为后面是(++i), 若不减一则从下标1开遍历,漏了一个数 int j = high; int temp = a[high]; while(1) { while(a[++i] < temp); while(a[--j] > temp); if (i<j) { swap(&a[i], &a[j]); } else { break; } } // 每一轮结束前,的最后一步,将mid跟temp比较 swap(&a[i], &a[high]); return i; } // 写法一 void QuickSort1(int * a, int low, int high) { if (low < high) { int mid = partition(a, low, high); QuickSort1(a, low, mid-1); QuickSort1(a, mid+1, high); } } // 写法二 void QuickSort2(int * a, int low, int high) { if (low >= high) return; int i = low; int j = high; int temp = a[low]; while(i<j) { while(i<j && temp <= a[j]) { j--; } a[i] = a[j]; while(i<j && temp >= a[i]) { i++; } a[j] = a[i]; } a[i] = temp; QuickSort2(a, low, i-1); QuickSort2(a, i+1, high); } int main() { int a[11] = {33, 40, 1, 14, 7, 35, 27, 9, 55, 80, 61}; QuickSort1(a, 0, 10); // 从下标0开始 printf("方法一: "); PrintSort(a, 11); int b[11] = {33, 40, 1, 14, 7, 35, 27, 9, 55, 80, 61}; printf("方法二: "); QuickSort2(b, 0, 10); PrintSort(b, 11); }