排序算法值快速排序

快速排序算法:

对于一个待排序列,确认出一个基准值key,将将序列分为小于基准值和大于等于基准值的两个序列,然后再将这两个序列再进行之前的操作分成新的两列,不断往下循环操作使数组分到的数组越来越小,如果分到的新序列里的元素为1或者为0,那么这个序列就是有序的了。
key值可以定为待排序列的第一个元素或者最后一个元素,对待排序列的分组操作有三种实现思想。

1.按基准值互划分左右区间:

  • huver法
  • 挖坑法
  • 前后指针法
1. 1hover法(前后指针法)

定义两个指针,begin指向待排序列的第一个元素,end指向待排序列的倒数第二个元素,将最后一个元素定位基准值key。
begin向后移动,当begin所指向的元素小于key时向后移动一个元素,当begin指向的元素大于等于key时begin停止后移,开始移动end,当end指向的元素大于等于key时,end向前移动一位,当end指向元素小于key时停止移动。交换begin和end指向元素,然后继续向后移动begin,大于key停止,向前移动end,小于key停止,begin和end交换所指向元素的值。重复指向这个操作,直至end和begin指向同一个元素。这是将这个元素和基准值进行交换。此时的序列就分为了小于begin指向的基准值的左边序列,和大于等于基准值的右边序列。

int hover(int array[], int left, int right){
	int begin = left;
	int end = right - 1;
	int key = array[right];
	while (begin < end){
		while (begin<end&&array[begin] < key)
			begin++;
		while (begin<end&&array[end] >= key)
			end--;
		Swap(array + begin, array + end);
	}
	Swap(array + begin, array + right);
	return begin;
}
1.2挖坑法

“挖坑法”听名字就是要从待排序列中取出一个元素,让序列中“空”出一个元素出来。第一步确定基准值key,将待排序列的最后一个元素定为基准值,将这个基准值“挖”出来,定义两个指针分别指向待排序列的第一个元素和倒二个元素分别为begin和end,begin所指向的元素小于key,begin向后移动,当begin指向元素大于key时,将这个元素“挖”出来将之前“挖”出的空填起来,然后移动end指针,当end指向的元素大于等于key时,向前移动一位,否则将end指向的元素“挖”起来,去“填”前面的坑,然后又开始向后移动begin,大于key就“挖”起来填后面的坑,向前移动end指针重复上面的操作,依次移动两个指针,直至两个指针指向同一个位置,而且这个位置是个“坑”,用key“填”这个“坑”,此时待排序列就被分为左边小于key的左序列,和右边大于等于key的右序列。

int potholing(int array[], int left, int right){
	int key = array[right];
	int begin = left;
	int end = right;
	while(begin < end){
		while (begin < end&&array[begin] < key)
			begin++;
		array[end] = array[begin];
		while (begin < end&&array[end] >= key)
			end--;
		array[begin] = array[end];
	}
	array[begin] = key;
	return begin;
}
1.3前后指针法

老规矩先确定基准值key为待排序列的最后一个元素,定义两个指针begin(初始化为待排序列的第一个位置),prev(初始化为待排序列的第一个位置之前的位置),分别指向右区间最后一个元素(大于等于基准值),左区间最后一个元素(小于基准值),begin,prev为元素的数组下标。两个指针都是先后移动。

先移动begin,当begin指向的元素大于key时begin向后移动,否则prev向后移动一位,交换两个指针指向元素的值,继续向后移动begin,循环以上操作,当begin遍历过待排序列的最后一个元素之后,循环结束,prev指向的元素的值就是key的值。此时待排序列就被分为左边小于key的左序列,和右边大于等于key的右序列。

int PartSort(int array[], int left, int right){
	int key = array[right];
	int begin = left;
	int prev = left - 1;
	while (begin <= right){
		if (array[begin] <= key){
			prev++;
			if (prev != begin)
				Swap(array + begin, array + prev);
		}
		begin++;
	}
	return prev;
}

2.快排实现

按照基准值将待排序列分为左区间后还需继续对两个区间在进行以上三种方法的划分,直至得到的子区间只有一个元素或者没有元素

void _QuickSort(int array[], int left, int right) {
	// 终止条件 size == 0 || size == 1
	// left == right	区间内还剩一个数
	// left > right		区间内没有数
	if (left == right) {
		return;
	}

	if (left > right) {
		return;
	}

	int div; // 比基准值小的放基准值左边,大的放右边后,基准值所在的下标
	div = PartSort(array, left, right);	// 遍历 array[left, right],把小的放左,大的放右
	//div=hover(array,left,right);
	//div=potholing(array, left, right);
	_QuickSort(array, left, div - 1);	// 分治解决左边的小区间
	_QuickSort(array, div + 1, right);	// 分治解决右边的小区间
}

总结:
快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
时间复杂度:O(N*logN)
稳定性:不稳定

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
冒泡排序算法快速排序算法是两种不同的排序算法,它们在效率和实现上有一些明显的区别。 冒泡排序是一种简单的比较排序算法,它通过依次比较相邻的元素并交换位置来排序。具体步骤如下: 1. 从第一个元素开始,依次比较相邻的两个元素,如果顺序错误则交换位置。 2. 重复上述步骤,直到没有需要交换的元素。 冒泡排序的时间复杂度是O(n^2),其中n是待排序元素的数量。它是一种稳定的排序算法,因为相等元素之间的顺序不会改变。但是冒泡排序在最坏情况下需要进行n次遍历,因此效率较低。 快速排序是一种基于分治思想的排序算法,它通过递归地将数组划分为较小和较大的两个子数组,并对这两个子数组分别进行排序。具体步骤如下: 1. 选择一个基准元素,并将其他元素与基准元素比较,将较小的元素放到基准元素的左边,较大的元素放到右边。 2. 对基准元素左右两侧的子数组递归进行快速排序快速排序的时间复杂度平均为O(nlogn),最坏情况下为O(n^2)。它是一种不稳定的排序算法,因为在交换过程中相等元素的顺序可能改变。快速排序通常比冒泡排序快得多,尤其是在大规模数据集上。 因此,虽然冒泡排序快速排序都是经典的排序算法,但在效率和实现上存在明显的差异。如果对于效率要求较高的排序任务,快速排序通常是更好的选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值