您的位置:首页 > 其它

排序算法总结---交换排序之快速排序

2014-12-09 09:10 459 查看
快速排序是对起泡排序的改进,起泡排序中,记录的比较和移动是在相邻位置进行的,记录每次交换只能后移一个位置,因而总的比较次数和移动次数较多。快速排序中,记录的比较和移动是从两端向中间进行的。

快速排序又称为分区交换排序,基本思想是:

首先选择一个轴值,将带排序记录划分成独立的两部分,左侧记录的关键码均小于或者等于轴值,右侧记录的关键码均大于或者等于轴值,然后分别对这两部分重复上述的过程,直到整个序列有序。

快速排序是一个递归的过程。

需要解决的问题:

1.如何选择轴值;

2.在待排序序列中如何进行划分(通常叫做一次划分);

3.如何处理划分得到的两个待排序子序列;

4.如何判别快速排序的结束。

问题1的解决:

选择轴值得方法很多,这里选择第一个记录作为轴值;

问题2的解决:对待排序序列进行一次划分的过程为:

①.初始化:取第一个记录作为轴值,设置两个参数i,j分别用来指示将要与轴值记录进行比较的左侧记录位置和右侧记录位置,也就是本次划分的区间。

②.右侧扫描过程:将轴值记录与j指向的记录进行比较。如果j指向记录的关键码大,则j前移一个记录的位置(j--)。重复右侧扫描的过程,直到右侧的记录小(即反序),若存在划分区间,则将轴值记录与j指向的记录进行交换;

③.左侧扫描过程:将轴值记录与i指向的记录进行比较。如果i指向记录的关键码小,则i后移一个记录的位置(i++)。重复左侧扫描的过程,直到左侧的记录大(即反序),若存在划分区间,则将轴值记录与i指向的记录进行交换;

④.重复②,③步,直到i,j指向同一位置,即轴值记录最终的位置。

#include <iostream>
#include <cstdlib>

using namespace std;
void swap(int *number1, int *number2)
{
	int temp = *number1;
	*number1 = *number2;
	*number2 = temp;
}
//快速排序一次划分算法
int Partition(int *array, int first,int end)
{
	int i = first;
	int j = end;
	while (i<j)
	{
		while (i<j && array[i] <= array[j])
		{
			j--;//右侧扫描
		}
		if (i<j)
		{
			swap(array[i], array[j]);
			i++;
		}
		while (i<j&&array[i]<=array[j])
		{
			i++;//左侧扫描
		}
		if (i<j)
		{
			swap(array[j], array[i]);
			j--;
		}
	}
	return i;
}
void QuickSort(int *array, int first,int end)
{
	if (first<end)
	{
		int pivot = Partition(array, first, end);
		QuickSort(array, first, pivot - 1);
		QuickSort(array, pivot + 1, end);
	}
}
void show(int *array, int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << array[i] << "  ";
	}
	cout << endl;
}
void main()
{
	int array[] = { 7, 6, 5, 4, 3, 2, 1, -1 };
	int end = sizeof(array) / sizeof(array[0]);
	QuickSort(array, 0,end-1);
	show(array, end);
	system("pause");
}


最好情况下和平均情况下的时间复杂度为:O(nlog2n),最坏的时间复杂度:O(n*n)

快速排序是一种不稳定的排序的方法。

递归调用栈的深度为:平均和最好O(log2n),最坏O(n)

快速排序的平均性能是迄今为止所有内排序算法中最好的一种。

快速排序使用于待排序记录个数很大且原始记录随机排列的情况。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: