Sorting Algorithm-Quick Sort

原创 2016年09月04日 11:25:39

Quick Sort-快速排序

Algorithm:

快速排序(Quick Sort)的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

Ex:我们围绕第一个元素55进行划分:所有小于55的元素都移到其左边,所有大于55的元素都移到其右边,接着对下标为0~2的子数组和下标为4~7的子数组分别进行递归排序,那么整个数组就排好序了。


Code1:

void Quick_Sort(vector<int> &v, int first, int end)
{
	if (first < end)
	{
		int key = v[first];
		int i = first;
		int j = end;
		while (i < j)
		{
			while (i < j&&v[j]>=key)
				j--;
			if (i < j)
				v[i] = v[j];
			while (i < j&&v[i] < key)
				i++;
			if (i < j)
				v[j] = v[i];
		}
		v[i] = key;  //此时i=j
		Quick_Sort(v, first, i-1);
		Quick_Sort(v, i+1, end);
	}
}

Code2:

int Partition(int data[], int length, int start, int end)  //分割
{
	int pivot = data[end];
	int curpos = start;
	for (int index = start; index < end; index++)
	{
		if (data[index] < pivot)
		{
			swap(data[index], data[curpos]);
			curpos++;
		}
	}
	swap(data[curpos], data[end]);
	return curpos;
}
void Quick_Sort(int data[],int length, int start, int end)
{
	if (start >= end)
		return;
	int index = Partition(data, length, start, end);
	if (start < index)
		Quick_Sort(data, length, start, index - 1);
	if (index < end)
		Quick_Sort(data, length, index + 1,end);
}


改进:

考虑一种极端的情况:n个相同元素组成的数组
对于这种输入,插入排序的性能非常好:每个元素移动的距离都为0,所以总的运行时间为O(n)
但对于快速排序的性能非常糟糕。n-1次划分中每次划分都需要O(n)时间来去掉一个元素,所以总的运行时间为O(n^2)。当n=1000000时,运行时间从一秒一下子变成了2小时。
用双向划分可以避免这个问题:
主循环中有两个内循环,第一个内循环将i向右移过小元素,遇到大元素时停止;第二个内循环将j向左移过大元素,遇到小元素时停止。然后主循环测试这两个下标是否交叉并交换它们的值。
这样遇到相同元素时停止扫描,并交换i和j的值。
这样虽然使交换的次数增加了,但却将所有元素都相同的最坏情况变成了nlog2n次比较的最好情况。

Code3:

void Quick_Sort2(int data[], int length, int start, int end)
{
	if (start >= end)
		return;
	int key = data[start];
	int i = start, j = end+1;
	while (1)
	{
		do{
			i++;
		} while (i <= end && data[i] < key);
		do{
			j--;
		} while (data[j] > key);
		if (i > j)
			break;
		swap(data[i],data[j]);
	}
	swap(data[start], data[end]);
	Quick_Sort2(data, length, start, j - 1);
	Quick_Sort2(data, length, j + 1, end);
}


Analysis:

1、最好的情况下,每次的划分都会恰好从中间将序列划分开来,那么只需要logn次划分即可划分完成,是一个标准的分治算法。
EX:  H A C B F E G D L I K J N M O
每一次划分都需要比较N次
复杂度为O(nlogn)
2、最坏的情况下,即序列已经排好序的情况下,每次划分都恰好把数组分成了0,n两部分,那么需要n次划分,但是比较的次数约为n,n-1,n-2,...1,所以整个比较次数约为n(n-1)/2~(n^2)/2。
3、平均情况下:1.39NlogN
比归并排序多了30%的比较,但是由于涉及了较少的数据交换和移动操作,比归并快
4、为了避免出现最坏的情况,可以首先对序列进行随机化
5、快速排序是in-place算法
6、快速排序是不稳定排序


Improvement:(C++ STL库函数排序算法)

1、当划分到较小的子序列时,通常可以使用插入排序替代快速排序
2、三平均区分法(Median of three partition)
选择待排数组最左边,最右边,最中间的三个元素的中间值作为中轴(pivot)
(1)使最坏情况发生的几率减少了
(2)其次防止边界情况
3、三分区(3-way partition)快速排序


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

相关文章推荐

Sorting Algorithm-Bubble Sort

冒泡排序-Bubble Sort Algorithm: 重复地走访过要排序的数列,一次比较两个元素,如果两个元素顺序错误,就把他们交换,知道没有再需要交换的元素为止像水中的泡泡一样,大的先冒出来,小的...

Sorting Algorithm-Shell Sort

Shell Sort-希尔排序 Algorithm: 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成...

C/C++ Quick Sort Algorithm

C/C++ Quick Sort Algorithm.
  • YhL_Leo
  • YhL_Leo
  • 2015年12月10日 21:35
  • 5056

quick_sort algorithm

算法思想:挖洞+填坑
  • yeruby
  • yeruby
  • 2014年05月16日 22:26
  • 723

Algorithm: Quick Sort Mind and Related Questions

Quick Sort 的演示: 1)随机取一个pivot(通常习惯是数组的最后一个元素) 快速排序的中心思想是找一个pivot(具体的数组的一个值,而非坐标),pivot是一个枢纽...

算法笔记(2) 冒泡排序和插入排序

冒泡排序思路1.循环获取列表每一个元素2.将该元素与其它元素比较交换,筛选出最大元素代码java版本/** * Created by lilongsheng on 2017/6/20. */ pu...

js-sorting-algorithm

  • 2017年07月09日 23:04
  • 916KB
  • 下载

sicily Sorting Algorithm 一道题玩一种排序之shell排序

题目DescriptionOne of the fundamental problems of computer science is ordering a list of items. There’...
  • mgsweet
  • mgsweet
  • 2016年12月30日 10:15
  • 152
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Sorting Algorithm-Quick Sort
举报原因:
原因补充:

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