返回顶部

快速排序

快排及快速排序,是排序算法中比较快速常用的一种排序方式


一 基本原理

快速排序的根本可以说就是通过分治法来实现,简单举一个例子来理解一下快速排序的过程。

我们现在对(56,28,45,93,10,32,44,95,60,58)进行排序。首先我们定义三个量,i,j,flag。i是数组第一个值的下表即i=0。j是数组最后一个值的下表即j=9,flag就是数组的第一个值即flag=56,现在我们要做的就是讲这个数组中所有比flag小的数放到他的前面,把所有比flag大的数放到他的后面。

  • 第一步从j开始向左(前)找,找到第一个比flag小的数,是下标为6的数44,我们就将44与flag56进行交换从而使数组变成(44,28,45,93,10,32,56,95,60,58),此时的j=6

  • 第二步从i开始向右(后)找,找到第一个比flag大的数,是下标为3的数93,我们就将93与flag56进行交换从而使数组变成(44,28,45,56,10,32,93,95,60,58),此时的i=3

  • 第三步继续从j(此时j=6)开始向左找,找到比flag小的数,是下标为5的数32,我们将32与flag进行交换,得到数组(44,28,45,32,10,56,93,95,60,58),此时j=5

  • 第四步从i(此时i=3)开始向右找,找到比flag大的数,直到i=j,我们发现在j之前已经找不到比flag更大的数,此时快速排序的第一轮就已经结束,这个时候在flag之前的数都是比他小的,在他之后都是比他大的,我们再将flag前后两片区域重新定义成新的无序的数组,分别对他们重复刚才的过程,直到分解到每个重新划分的区域内只有一个值,排序就算完成了。我们直接将过程贴在下面

    (44,28,45,32,10)(56)(93,95,60,58)

    (10,28,45,32,44)(56)(58,95,60,93)

    (10,28,44,32,45)(56)(58,93,60,95)

    (10,28,32,44,45)(56)(58,60,93,95)

    (10,28,32)(44)(45)(56)(58)(60)(93)(95)

    (10)(28)(32)(44)(45)(56)(58)(60)(93)(95)

排序结束

二 稳定性问题

  首先大家应该都知道快速排序是一个不稳定排序算法,那么到底什么才是排序的稳定性呢,我认为通俗的讲有两个相同的数A和B,在排序之前A在B的前面,而经过排序之后,B跑到了A的前面,对于这种情况的发生,我们管他叫做排序的不稳定性,而快速排序在对存在相同数进行排序时就有可能发生这种情况。

  例如(5,3A,6,3B)对这个进行排序,排序之前相同的数3A与3B,A在B的前面,经过排序之后会变成(3B,3A,5,6),所以说快速排序是一个不稳定的排序

三 时间复杂度

== 简单的总结一下快速排序的时间复杂度问题 ==

  • 最优情况:每一次的flag刚好都可以平分整个数组,此时的时间复杂度为O(nlogn)

  • 最坏情况:每一次的flag刚好都是最大或者最小的数,此时的时间复杂度为O(n2)

  • 平均情况:经过推到平均情况为O(nlogn)

代码演示

/*
*qsort 快速排序
*@auther Tong_WY
*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
int a[200];
//定义快排函数
void qsort(int l, int r) {
	int i, j, mid, t;
	i = l;
	j = r;
	mid = a[(l + r) / 2];
	do {
		while (a[i] < mid) i++;		//寻找左边小于mid的数
		while (a[j] > mid) j--;     //寻找右边小于mid的数
		if (i <= j) {
			t = a[i];		        //进行数值交换
			a[i] = a[j];
			a[j] = t;
			i++;			        //继续寻找
			j--;
		}
	} while (i <= j);
	if (j > l) qsort(l, j);			//继续快排左右子序列
	if (i < r) qsort(i, r);
}

int main(){
	int n;
	cin>>n;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	qsort(1, n);
	for (int i = 1; i <= n; i++)
		cout << a[i] << " ";
	return 0;
}

PS

  • C++中有自带的快排库(),用法:sort(*array+left , *array+right)

  • C中的库是在(<stdlib.h>)中
    用法:

qsort(a, 1000, sizeof(int), cmp);
//其中cmp函数应写为:
int cmp(const void *a, const void *b)
{
    return *(int*)a - *(int*)b; //由小到大排序
    //return *(int *)b - *(int *)a; 由大到小排序
}
posted @ 2020-10-16 19:26  Shamero  阅读(104)  评论(0)    收藏  举报