排序:1.3、快速排序


前言

我们之前介绍的桶排序利用数组排序,虽然操作简便,时间性能上也很是友好,O(M+N),然而却有不少致命的缺陷,比如浪费空间。而冒泡排序虽然解决了空间上的浪费,但是双重循环下的两两互换,在时间性能上却是得不偿失,O(N^2),空有名字的浪漫,却是一无是处。
那么是否有一种时间和空间上的双重友好呢?显然是有的,这么我们简单的介绍一下,Charles Antony Richard Hoare先生在1960年提出的快速排序。


一、快速排序

首先随便给出我们要排序的一组数值:
如:5、3、8、9、6、1、2、7、4、10
我们这边以最左边的值5设置为基准数,就是一个随便给的名字,你叫它张三也可以。以基准数为轴,将这些数值化为两部分,左边都小于基准数,而右边都大于基准数。
怎么操作呢?对值的操作归根结底还是互换。这边我们给出 i 和 j 两个下标,分别指向最左边和最右边。基准数在最左边,我们就从最右边 j 开始移动,再从左边 i 移动。这边可以自己推演一下,如果是同端移动,即左边开始移动,会出现问题。
j 所指的值,若大于5,则j–;
然后换i移动,i所指的值,若小于5,则i++;

		while (a[j] >= a[left] && i < j)
		{
			j--;
		}

		while (a[i] <= a[left] && i < j)
		{
			i++;
		}
不然则就兑换值,继续移动。
		int t = 0;
		t = a[i];
		a[i] = a[j];
		a[j] = t;
直至i、j同时指向相同的数。这时则与基准数兑换,即可完成以基准数未轴的二分。
	a[left] = a[i];
	a[i] = temp;
进而以此类推,采用递归的方式进行划分。
	quickSort(a, left, i - 1);
	quickSort(a, i+1, right);

这里我们提供一次划分的动向过程:
原:5、3、8、9、6、1、2、7、4、10
①:5、3、4、9、6、1、2、7、8、10
②:5、3、4、2、6、1、9、7、8、10
③:5、3、4、2、1、6、9、7、8、10
④:1、3、4、2、5、6、9、7、8、10
这时就完成了第一次的二分。之后,一分为二继续排序划分,直至完成排序。

二、快速排序源码

#include <iostream>
using namespace std;

void quickSort(int a[],int left, int right)
{
	if (left > right)
	{
		return;
	}

	int i = left, j = right, temp = a[left];
	while (i != j)
	{
		while (a[j] >= a[left] && i < j)
		{
			j--;
		}

		while (a[i] <= a[left] && i < j)
		{
			i++;
		}

		int t = 0;
		t = a[i];
		a[i] = a[j];
		a[j] = t;
	}

	a[left] = a[i];
	a[i] = temp;

	quickSort(a, left, i - 1);
	quickSort(a, i+1, right);

}

int main()
{
	cout << "排序的个数:";
	int sortLenght = 0;
	cin >> sortLenght;
	int* a = new int[sortLenght];
	cout << "输入要排序的数值:" << endl;
	for (int i = 0; i < sortLenght; i++)
	{
		cout << "第" << i + 1 << "个数:";
		cin >> a[i];
	}
	cout << "未排序的序列:";
	for (int i = 0; i < sortLenght; i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;

	quickSort(a, 0, sortLenght - 1);

	cout << "排序完的序列:";
	for (int i = 0; i < sortLenght; i++)
	{
		cout << a[i] << " ";
	}

	return 0;
}

三、结果

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值