c++实现快速排序

原创 2016年05月31日 17:54:15

1、算法思想
     快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod) ,
分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。

2、快排步骤:

①分解: 
    
 在R[low..high]中任选一个记录作为基准(Pivot),以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
 注意:划分的关键是要求出基准记录所在的位置pivotpos。划分的结果可以简单地表示为(注意pivot=R[pivotpos]): R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys     其中low≤pivotpos≤high。

②求解: 
     
通过递归调用快速排序对左、右子区间R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。

③组合: 
    
 因为当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作。

通俗理解核心步骤:

1.i =L; j = R; 将基准数备份形成第一个可以看成空值的a[i]。

2.j--由后向前找比它小的数,找到后把此数填前一个a[i]中。

3.i++由前向后找比它大的数,找到后也把此数填到前一个坑a[j]中。

4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中

3、算法性能

时间复杂度:O(n*lgn)
最坏:O(n^2)
空间复杂度:O(n*lgn)
不稳定。

实现代码:

//先上递归版

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <stack>
using namespace std;
#define  MAX 101
int Partition(int num[], int low, int high)
{	                                 //int pivotkey;这个枢轴的选取很关键,改进版的可以用三数取中,就九数取中等
	int pivotkey = num[low];         //在这里就取第一个元素
	num[0] = pivotkey;               //备份到num【0】,
	while (low < high)
	{
		while (low < high&&num[high] >= pivotkey)
			high--;
		num[low] = num[high];            //不满足循环条件就执行这个语句,因为备份出【low】,所以可以覆盖他,这也是这个while在                                                 //前面的原因。否则【high】会丢失的。
		while (low < high&&num[low] <= pivotkey)
			low++;
		num[high] = num[low];
		                             //交换low,是因为low=pivotkey,比较了。
	}
	num[low] = num[0];
	return low;                         //最后high和low在某一个位置相遇,就是切分部的值。
}

void Qsort1(int num[], int low, int high)   //对随机产生的无序数组进行快速排序,这也是二分法的缺陷之一。
{                                           //快排对很多数据更有优势,可以设置一个数据个数的阈值,才进行快排,这里也是一个优化的地方
	int pivot;//
	if (low < high)
	{
		pivot = Partition(num, low, high);   //轴值所在的位置
		Qsort1(num, low, pivot - 1);         //递归的深度决定了时间的复杂度。
		Qsort1(num, pivot + 1, high);
	}
}

//非递归版,模拟栈的
inline void push2(stack<int> &s, int l, int r)
{
	s.push(r);
	s.push(l);
}
void Qsort(int num[], int l, int r)
{
	stack<int> s;
	push2(s, l, r);
	int lwalker, rwalker, mid;
	while (!s.empty())
	{
		int left = s.top(); s.pop();
		int right = s.top(); s.pop();
		lwalker = left;
		rwalker = right;
		mid = num[(lwalker + rwalker) / 2];
		while (lwalker < rwalker)
		{
			while (num[lwalker] < mid) lwalker++;
			while (num[rwalker]>mid) rwalker--;
			if (lwalker <= rwalker)
			{
				int tmp = num[lwalker];
				num[lwalker] = num[rwalker]; 
				num[rwalker] = tmp;
				lwalker++;
				rwalker++;
			}
		}
		if (lwalker < right)  push2(s, lwalker,right);
		if (rwalker>left)  push2(s, left, rwalker);
	}
}

void input(int num[])//实参传入的数组的首地址,而不是整个数组
{
	int i;
	srand((unsigned)time(NULL));//产生随机函数的随机数种子
	for (i = 1; i < MAX; i++)
	{
		num[i] = rand() % 100;
	}
}
void  output(int num[])
{
	int i;
	for (i = 1; i <= MAX; i++)
	{
		printf("%5d", num[i]);
		if (i % 100 == 0)
			printf("\n");
	}
}
void main()
{ 
	int num[MAX],num2[MAX];
	time_t start, end;
	time(&start);
	input(num);
	cout << "递归排序前:" << endl;
	output(num);

	Qsort1(num, 0,MAX - 1);
	cout << "递归排序后:" << endl;
	output(num);

	input(num2);
	cout << "开始非递归排序,排序前:"<<endl;
    output(num2);

	cout << "非递归排序后:" << endl;
	Qsort(num2, 0, MAX - 1);
	output(num2);

	time(&end);
	cout << "用时为" << end-start << endl;
	system("pause");
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

快速排序的迭代实现c++

  • 2013年12月05日 09:12
  • 2KB
  • 下载

快速排序的C++和python实现

  • 2013年03月14日 10:14
  • 808B
  • 下载

算法导论 - QuickSort 快速排序 C++实现

算法导论的快速排序还和一般书上的快速排序是有点不一样的。 当然书习题也给出了一般快速排序的方法,其分区函数学名叫Hoare partition。 书本介绍的排序可以用图看的很清晰: 然后配合C++...
  • kenden23
  • kenden23
  • 2013年11月09日 10:32
  • 13182

C++快速排序算法实现

  • 2015年12月07日 16:04
  • 475B
  • 下载

用C++实现快速排序

  • 2009年11月24日 00:27
  • 238KB
  • 下载

快速排序(快排)算法的C++两种实现

快排算法在分治的时候有两种实现,一种实现是从两边到中间(partition),另一种实现是从一边到另一边(partition2)。我用一个100000数组测试发现前一种实现运行速度快一些。 这两种的...

快速排序与堆排序的C++实现

  • 2013年08月17日 06:55
  • 259KB
  • 下载

C++实现快速排序QuickSort

快速排序是典型的分治思想算法。每一遍排序都从序列中取一个值,并且使这个值左边的数都小于等于这个值,右边的都大于等于这个值,这样把整个序列分为两部分,再对这两部分分别递归执行上述操作。 该方法的基本思...

c++实现堆排序和快速排序比较

  • 2014年10月30日 11:26
  • 5KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++实现快速排序
举报原因:
原因补充:

(最多只允许输入30个字)