快速排序,时间复杂度O(NlgN)

8 篇文章 0 订阅

本次文章所讲是快速排序,虽说是快速排序,但在某些情况下本排序的时间复杂度会等于N2.

代码如下,实现降序。

#include<stdio.h>
int pr(int left, int right);//降序函数
int a[101];//全局数组,静态变量,可以在主函数main中与降序数组中访问。
int main()
{
	int left, right;//定义左右端。
	int n;
	scanf("%d", &n);//选择排序的大小
	for (int i = 0; i < n; i++)//赋值
		scanf("%d ", &a[i]);
	left = 0;
	right = n-1;
	pr(left, right);
	for (int j = 0; j < n; j++)
		printf(" %d ", a[j]);
	getch();
	return 0;
}
int pr(int left, int right)
{
	int team;
	if (left > right)//结束函数的条件
		return;
	int i = left;
	int j = right;
	while (i != j)
	{
		while (a[j] <= a[left] && j > i)
			j--;
		while (a[i] >= a[left] && i < j)
			i++;
		if (i < j)
		{
			team = a[i];
			a[i] = a[j];
			a[j] = team;
		}
	}
	team = a[i];
	a[i] = a[left];
	a[left] = team;
	pr(left, i -1);
	pr(i + 1, right);

}

该算法的核心是找到一个基准,进行数次排序,每次排序完后左边是小于基准的数,右边是大于基准的数。

更新一下,下面使用栈来实现

#include<iostream>
#include<stack>
#include<vector>
using namespace std;
void swap(int &a, int &b)
{
	int c = a;
	a = b;
	b = c;
}
int sort(vector<int> &a,int left,int right)
{
	int i = left;
	int j = right;
	while (i < j)
	{
		while (i<j&&a[i]>a[left])
			i++;
		while (i <j&&a[j] <= a[left])
			j--;
		swap(a[i], a[j]);
	}
	return j;
}
void quick_sort(vector<int> &a, int left, int right)
{
	stack<int> s;
	if (left < right)
	{
		int n = sort(a, left, right);
		if (n - 1>left)
		{
			s.push(left);
			s.push(n - 1);
		}
		if (n + 1 < right)
		{
			s.push(n + 1);
			s.push(right);
		}
		while (!s.empty())
		{
			int r = s.top();//出栈
			s.pop();//删除栈顶的元素
			int l = s.top();
			s.pop();
			n = sort(a, l, r);
			if (n - 1 >l)
			{
				s.push(l);
				s.push(n - 1);
			}
			if (n + 1 <r)
			{
				s.push(n + 1);
				s.push(r);
			}
		}
	}
}
void main()
{
	vector<int> a{ 9,2,4,1,4 };
	quick_sort(a, 0, 4);
	for (auto b : a)
		cout << b << " ";
	system("pause");
}

这段代码对于比较的我思考了很长时间,可以这样理解,我们始终对于i指向的位置都是小于我们的

基准数a[left】的,于是每当j找到大于基准数时,我们一交换,那么很容易得出当我们i和j相遇

的位置便是中心点。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值