2021-10-20 漫画算法 小灰的算法之旅--第四章 排序算法(二)

排序算法

快速排序

是冒泡排序演变而来,基于分治法
即每一轮挑选一个元素,并让其他比它大的元素移动到数列的一边,比它小的元素移动到数列的另一边,从而把数列拆解成两个部分
时间复杂度为O(nlogn)

基准元素的选择

最简单的方式选择数列的第一个元素
但是如果这个元素是该数列的最大值或最小值,则排序时无法将数列拆解成两部分,时间复杂度会退化成O(n^2)
第二个方法是随机选择数列中的元素作为基准元素,但是还是有几率影响分治的效果

具体方法

  • 双边循环法
  • 单边循环法

双边循环法

1.选定基准元素P,设定两个指针分别指向最左L和最右R的元素
在这里插入图片描述
2.第一次循环
从R开始,如果R >= P,R指针左移,否则停止,切换到L指针
从L开始,如果L <= P,指针右移,否则停止
在这里插入图片描述
3.L也停止之后,交换L与R的值
在这里插入图片描述
4.第二次循环
重新切换到R指针向左移,因为8>4,继续左移,2<4,停在2的位置,切换到L指针向右移
在这里插入图片描述
5.L也停止之后,交换L与R的值
在这里插入图片描述
6.第三次循环
在这里插入图片描述
7.交换元素
在这里插入图片描述
8.第四次循环
L指针与R指针重合,移动停止
在这里插入图片描述
9.最有把P与重合点的元素进行交换
在这里插入图片描述
这一轮宣告结束,P两端的元素分别进行下一轮

代码如下:

public static void quickSort(int[] arr, int startIndex, int endIndex)
{
	//递归结束
	if(startIndex >= endIndex)
	{
		return;
	}
	//基准 元素
	int pivotIndex = partition(arr, startIndex, endIndex);
	quickSort(arr, startIndex, pivotIndex - 1);
	quickSort(arr, pivotIndex + 1, endIndex);
}
private static int partition(int[] arr, int startIndex, int endIndex)
{
	//取第一个位置的元素作为基准元素
	int pivot = arr[startIndex];
	int left = startIndex;
	int right = endIndex;
	while(left != right)
	{
		while(left < right && arr[right] > pivot)
		{
			right --;
		}
		while(left < right && arr[left] <= pivot)
		{
			left ++;
		}
		if(left < right)
		{
			int p = arr[left];
			arr[left] = arr[right];
			arr[right] = p;
		}
	}
	arr[startIndex] = arr[left];
	arr[left] = pivot;	
	
	return left;
}

单边循环法

1.选定基准元素P,同时设置一个M指针代表小于基准元素的区域边界
在这里插入图片描述
2.从左到右遍历
如果遍历到的元素 > P,则继续往后遍历
如果遍历到的元素 < P,则将M指针右移,并且将遍历到的元素和M指针所在位置的元素交换位置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.遍历到5,5 > 4,继续遍历
在这里插入图片描述
4.遍历到6,6 > 4,继续遍历
在这里插入图片描述
5.遍历到2,2 < 4,M指针右移,并交换元素
在这里插入图片描述
在这里插入图片描述
6.遍历到8,8 > 4,继续遍历
在这里插入图片描述7.遍历到1,1 < 4,M指针右移,并交换元素
在这里插入图片描述
在这里插入图片描述
8.最后交换P和M
在这里插入图片描述
这一轮宣告结束,M两端的元素分别进行下一轮

代码如下:

public static void quickSort(int[] arr, int startIndex, int endIndex)
{
	if(startIndex >= endIndex)
	{
		return;
	}
	int pivotIndex = partition(arr, startIndex, endIndex);
	quickSort(arr, startIndex, pivotIndex - 1);
	quickSort(arr, pivotIndex + 1, endIndex);
}
privat static int partition(int[] arr, int startIndex, int endIndex)
{
	int pivot = arr[startIndex];
	int mark = startIndex;
	
	for(int i = startIndex + 1; i <= endIndex; i ++)
	{
		if(arr[i] < pivot)
		{
			mark ++;
			int p = arr[mark];
			arr[mark] = arr[i];
			arr[i] = p;
		}
	}
	arr[startIndex] = arr[mark];
	arr[mark] = pivot;
	
	return mark;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值