欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

排序算法-快速排序

程序员文章站 2022-07-08 22:20:18
...
简介:

快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快排同冒泡都属于交换排序。不同的是,冒泡排序一次只能消除一个逆序对,而快排一次可以消除多个。

图解:

排序算法-快速排序

实现思路 A:

通过上图可以发现,我们通过寻找一个轴点(上图为5)使轴点两侧满足:左侧不大于轴点,右侧不小于轴点。通过分治,可以使序列中任意一点都满足上述要求。
步骤:

  1. 寻找轴点
  2. 划分序列,再次寻找轴点,直至到达单个序列(单个数值有序)
寻找轴点步骤:
  1. 随机的在序列中选取一个数m,同序列最左侧(low)值替换,从而空出low位置
  2. 从两个方向遍历序列(low -> hight,hight - > low)
  3. 若low指向的值小于m,则low右移。否则将low指向的值交换
  4. 另一个方向,操作相反

关于上述值交换:因为lo(以下low简称lo,height简称hi)位置已空出。则我们可以先从hi方向左移遍历。若遇到小于m的情况,则将当前值移到 lo 位置(此时hi指向的位置已空出)。然后从lo方向右移遍历。若遇到大于m的情况,则将当前值移到 hi 位置。重复此过程,直至 lo = hi。

代码:
#include<bits/stdc++.h>
using namespace std;

int partition(int *n, int lo, int hi){
 	swap(n[lo], n[lo + rand()%(hi - lo + 1)]);
 	int m = n[lo];
 	while(lo < hi){
  		while((lo < hi) && (n[hi] >= m))
   			hi--;
  		n[lo] = n[hi];
  		while((lo < hi) && (n[lo] <= m))
   			lo++;
  		n[hi] = n[lo];
 	}
 	n[lo] = m;
 	return lo;
}

void quick_sort(int *n, int lo, int hi){
 	if(lo >= hi) return;
 	int mi = partition(n, lo, hi);
 	quick_sort(n, lo, mi);
 	quick_sort(n, mi + 1, hi);
}

int main(){
 	int len = 5;
 	int n[len];
 	for(int i = 0; i < len; i++)
  		cin >> n[i];
 	quick_sort(n, 0, len - 1);
 	for(int i = 0; i < len; i++)
  		cout << n[i] << " ";
 	return 0;
}