快速排序算法

       快速排序(Quick Sort)算法是冒泡排序算法的一种改进。相比冒泡排序算法,快速排序算法元素间比较的次数较少,因此排序效率高,故得名快速排序。

快速排序算法的基本思想:

       通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分继续进行排序,以达到整个序列有序的目的。

    假设待排序的序列为(k1,k2,.......,kn),low为序列的低端下表,heigh为序列的高端下标,从序列中任选取一个元素作为轴元素(也叫基准元素),通常选择,将小于轴元素的所有元素都移到轴元素的左边,将大于基准元素的所有元素移动到右边,由此以轴元素为界,将序列划分为连个子序列,轴元素前面的子序列都小于轴元素,轴元素后面的子序列中的元素都大于轴元素。该轴元素的位置就是该元素经排序后再序列中的最终位置。这个过程称为一趟快速排序,或者叫做快速排序的依次划分。

    接下来分别对轴元素前后两个子序列进行相同的递归快速排序,递归算法的退出出口是heigh <= low。

递归算法的实现:

void QuickSort(int *array, int size)
{
    QuickSort(array, 0, size - 1);
}

void QuickSort(int* array, int low, int heigh)
{
	assert(array);
	if(low >= heigh)//表示已经完成一次快速排序
	{
		return;
	}
	int index = PartSort(array, low, heigh);//轴元素的位置
	QuickSort(array, low, index - 1);
	QuickSort(array, index + 1, heigh);
}

PartSort()函数是进行一次快排的算法。
对于快速排序的一次排序,有很多种算法,我这里列举常用的三种。

1、左右指针法

实现思路:

  ①、选取一个关键字(key)作为轴元素,一般取序列的第一个数或最后一个元素,这里采用选取序列最后一个元素为轴元素。

  ②、设置两个变量low = 0; heigh = size - 1;

  ③、从low一直向后走,直到找到一个大于 key 的值,heigh 从后至前,直至找到一个小于 key 的值,然后交换这两个数。

  ④、重复第③步,一直往后找,直到 low 和 heigh 相遇,这时将 key 放置 low 的位置即可。

当low >= heigh时,这时将Key和array[low]的值进行一次交换,一趟快速排序就完成了。

代码实现如下:

int PartSort(int *array, int low, int heigh)
{
	int key = array[heigh];
	while( low < heigh )
	{
		while(low < heigh && array[low] <= key)
		{
			++low;
		}
		while(low < heigh && array[heigh] >= key)
		{
			--heigh;
		}
		swap(array[low], array[heigh]);//交换两元素位置
	}
	swap(array[low],key);
	return low;
}

2、挖坑法

   挖坑法和左右指针法思想类似

  实现思路:

 ①、选取一个关键字(key)作为轴元素,一般取整组记录的第一个数或最后一个,这里采用选取序列最后一个数为轴元素。将该值保存下来,这样序列最后一个位置就可以随意覆盖,此时序列最后一个位置就形成了一个坑。

 ②、设置两个变量 low = 0; heigh = size - 1;

 ③、从 low 一直向后走,直到找到一个大于 key 的值,然后将该数放入坑中,坑位变成了 low 指向的位置;

 ④、heigh 一直向前走,直到找到一个小于key的值,然后将该数放入坑中,坑位变成了 heigh 指向的位置。

 ⑤、重复③和④的步骤,直到 low 和 heigh 相遇,然后将key放入最后一个坑位。


当 low >= heigh 时,将key放入最后一个坑,就完成了一次排序。
注意 ,因为 low 先走,所有最后一个坑肯定在 heigh 指向的位置。

代码实现如下:

int PartSort(int *array, int low, int heigh)
{
	int key = array[heigh];
	while(low < heigh)
	{
		while(low < heigh && array[low] <= key)
		{
			++low;
		}
		array[heigh] = array[low];
		while(low < heigh && array[heigh] >= key)
		{
			--heigh;
		}
		array[low] = array[heigh];	 
	}
	array[heigh] = key;
	return heigh;
}

3、前后指针法

 实现思路:

①、定义变量cur指向序列的开头,定义变量pre指向cur的前一个位置。

②、当 array[cur] < key 时,cur 和 pre 同时往后走,如果 array[cur] > key,cur 往后走,pre 留在大于 key 的数值前一个位置。

③、当 array[cur] 再次 < key 时,交换 array[cur] 和 array[pre]。

通俗一点就是,在没找到大于key值前,pre永远紧跟cur,遇到大的两者之间机会拉开差距,中间差的肯定是连续的大于key的值,当再次遇到小于key的值时,交换两个下标对应的值就好了。
实现代码如下:

int PartSort(int *array,int left, int right)
{
	if(left < right){
		int key = array[right];
		int cur = left;
		int pre = cur - 1;
		while(cur < right)
		{
			while(array[cur] < key && ++pre != cur)//如果找到小于key的值,并且cur和pre之间有距离时则进行交换。注意两个条件的先后位置不能更换
			{
				swap(array[cur],array[pre]);
			}
			++cur;
		}
		swap(array[++pre], array[right]);
		return pre;
	}
	return -1;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值