快速排序思路
实现方法
快速排序解法一(剑指offer 80页)
以data[end]为基准进行快速排序(原书上是随机选择一个位置index,将data[index]与data[end]元素调换位置,再以end为基准进行排序,此处为了对比清晰,直接以data[end]为基准),指针small=start-1、index=start,index指针从头开始遍历直到index>=end。遍历时,每次判断data[index]是否小于data[end],若是,small指针也往前一步,然后判断一下index与small是否相等,若不等(说明出现大于data[end]的数,把它往右移,如9和3,4,5互换),交换data[index]和data[small]。直到index遍历结束,small往前一步(因为当前data[small]是比data[end]小的数,所以需要往前一步,使得与data[end]交换之后,比data[end]小的数都在它左边),交换data[small]和data[end]。以small位置为中心,再以同样步骤递归(start,small-1)和(small+1,end)部分。
#include <iostream> #include <stdio.h> #include <stdexcept> #include <time.h> #include<stdlib.h> void Swap(int*a, int*b) { int temp; temp = *a; *a = *b; *b = temp; } int Partition(int data[], int length, int start, int end) { if (data == nullptr || length <= 0 || start < 0 || end >= length) throw "invalid parameters"; int small = start - 1; for (int index = start; index < end; ++index) { if (data[index] < data[end]) { ++small; if (small != index) Swap(&data[index], &data[small]); } } ++small; Swap(&data[small], &data[end]); return small; } void QuickSort(int data[], int length, int start, int end) { if (start == end) return; int index = Partition(data, length, start, end); if (index > start) QuickSort(data, length, start, index -1); if (index < end) QuickSort(data, length, index + 1, end); } int main() { int data[] = {6,1,2,7,9,3,4,5,10,8}; QuickSort(data, 10, 0, 9); for (int i = 0; i < 10;i++) { printf("%4d",data[i]); } }
快速排序解法二(数据结构274页 严蔚敏版)
以data[first]为基准,last先从后向前搜索,发现比基准小的,data[first]=data[last];first从前向后搜索,发现比基准大的,data[last]=data[first];直到first与last重逢,将key赋值给data[first]。以first为中心,递归(low,first-1)和(first+1,high)。
#include <iostream> using namespace std; void Qsort(int a[], int low, int high) { if(low >= high) { return; } int first = low; int last = high; int key = a[first];/*用字表的第一个记录作为枢轴*/ while(first < last) { while(first < last && a[last] >= key) { --last; } a[first] = a[last];/*将比第一个小的移到低端*/ while(first < last && a[first] <= key) { ++first; } a[last] = a[first]; /*将比第一个大的移到高端*/ } a[first] = key;/*枢轴记录到位*/ Qsort(a, low, first-1); Qsort(a, first+1, high); } int main() { int a[] = {6,1,2,7,9,3,4,5,10,8}; Qsort(a, 0, sizeof(a) / sizeof(a[0]) - 1);/*这里原文第三个参数要减1否则内存越界*/ for(int i = 0; i < sizeof(a) / sizeof(a[0]); i++) { cout << a[i] << " "; } return 0; }/*参考数据结构p274(清华大学出版社,严蔚敏)*/
快速排序解法三(链接)
以data[first]为基准,last先从后向前搜索,发现比基准小的,停下;first从前向后搜索,发现比基准大的,停下,交换data[last]和data[first];直到first与last重逢。以first为中心,递归(low,first-1)和(first+1,high)。
快速排序解法四(链接)
#include <iostream> using namespace std; void Swap(int*a, int*b) { int temp; temp = *a; *a = *b; *b = temp; } void Qsort(int a[], int low, int high) { if(low >= high) { return; } int first = low; int last = high; int key = a[first];/*用字表的第一个记录作为枢轴*/ while(first < last) { while(first < last && a[last] >= key) { --last; } Swap(&a[first], &a[last]); while(first < last && a[first] <= key) { ++first; } Swap(&a[first], &a[last]); } Qsort(a, low, first-1); Qsort(a, first+1, high); } int main() { int a[] = {6,1,2,7,9,3,4,5,10,8}; Qsort(a, 0, sizeof(a) / sizeof(a[0]) - 1); for(int i = 0; i < sizeof(a) / sizeof(a[0]); i++) { cout << a[i] << " "; } return 0; }
四种方法的比较
1、剑指offer | 采用两个指针,寻找比基准大的数,往后移,快排的思想不够直接。 |
2、数据结构严蔚敏 | 与4类似,但它不是交换,而是赋值,把小的赋值给data[first](从后往前),大的赋值给data[end](从前往后) |
3、博客1 | 与4类似,但它是从后往前找到小于基准的数后,停下不做任何操作,等从前往后找到大于基准的数后,交换data[first]和data[end] |
4、博客2 | 与2类似,它是直接交换data[first]和data[end](两个方向都是) 与3类似,它不管从前往后、从后往前,每次寻找到符合要求的数后,交换data[first]和data[end] |