快速排序

原创、转载请注明出处。

 

快速排序优点

速度快,不需要辅助空间。

 

分治

划分问题:把数组的各个元素重排后分成左右2部分,使得左边任意元素都小于或等于右边任意元素。

递归求解:把左右2部分分别排序。

合并问题:不用合并,因为此时数组已经完全有序。

 

“划分过程”有多个版本,我第一次用的把第一个数作为基准,从前向后和从后向前分别找1个(找2个),交换。在处理细节时很麻烦,出了很多问题,后来用了找一个就交换的方法,个人感觉细节问题较少,代码如下:

 

#include "stdafx.h"
#include <iostream>
using namespace std;


void mswap(int&a, int&b)
{
	if (a != b)
	{
		a ^= b;
		b ^= a;
		a ^= b;
	}
}

void qsort(int A[], int x, int y)
{
	if (x >= y)
		return;
	int i = x, j = y;
	while (i < j)
	{
		while (i < j&&A[i] < A[j])
		{
			j--;
		}
		mswap(A[i], A[j]);
		while (i < j&&A[i] < A[j])
		{
			i++;
		}
		mswap(A[i], A[j]);
	}
	qsort(A, x, i - 1);
	qsort(A, i + 1, y);
}

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

  

 20

6 1 5 4 8 3 9 12 51 11 15 14 13 25 69 47 56 74 26 78

 

快速选择问题:

输出一个序列排序后第k大的数。借鉴快速排序的思想,序列分成2个左右2个序列后,可以根据第一序列的长度和k比较来确定是在左序列还是在右序列找。

 

快速排序的时间复杂度为:最坏情况O(n2),平均情况O(nlongn),但实践中几乎不可能达到最坏的情况,效率非常高。根据快速排序思想,可以在平均O(n)时间内选出数组中第k大的元素。

 

posted @ 2017-10-21 19:33  哲贤  阅读(205)  评论(0编辑  收藏  举报