荷兰国旗问题(分三块)

在说 “荷兰国旗” 问题之前,首先来看一个引例。

  • 给定一个数组arr,和一个数num,请把小于等于num的数放在数组的左边,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度 O(N)

分析: 设定一个小于等于区,从0开始比较,如果当前数字小于等于num ,让其与小于等于区的下一个值做交换,再将小于等于区扩大一位,直到将所有的数字都与num进行过比较。重新排好的数组就是所求的数组。如下给出示意过程:
在这里插入图片描述
在这里插入图片描述
最终就可以得到一个在num左边所有的数都小于等于num右边都大于num。
这个过程实际上可以看成是小于等于区域在推着大于等于区域向右走,而当遇到小于等于num的数时,进行的操作是,与大于区域的第一个数字做交换,这听起来就有些像堆排序的heapify过程。

荷兰国旗问题(直观的“分三块”的问题)

—— 有了上面这些问题的基础,荷兰国旗问题就会好想一些。

  • 给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)

分析: 上一个题目要求将数组分成两块,而这个是将数组分成三块。上一个问题是在左边设置了一个大于等于区,这个问题可以在左边设置一个小于区,在右边设置一个大于区,不断向中间逼近,最终中间就是相等的数字。操作过程也和上一个问题是完全一样的。如下过程所示:
在这里插入图片描述

在这里插入图片描述

这样就将数组分成了不同条件的三块。以下给出算法代码:

  1. 在arr[L…R]范围上,根据数字p分块
  2. 小于p的在左边 等于p的在中间 大于p的在右边
  3. 返回值含义: 一定会返回一个长度为2的数组,等于区域的左边界和右边界(也就是相等区域的边界范围 )。
int* partition(int arr[],int L,int R,int p)
{
	int less=L-1; //小于区的右边界
	int more=R+1; //大于区的左边界
	int index=L;
	while(index<more)
	{
	    //分成三种情况讨论
		if(arr[index]<p) 
		{
			swap(arr,++less,index++);
		}
		else if(arr[index]>p)
		{
			swap(arr,--more,index);
		}
		else
		{
			index++;
		}
	}
	 int ans[2]={less+1,more-1};
	 return ans;
}

4.若无等于区域,此时返回值,左边界大于右边界。
在这里插入图片描述
将这个方法与快速排序的查找枢轴值的方法进行比较,看看有什么异同。 快速排序就是一个递归的此过程。在一定区域内进行划分,最终整体都有序。

——————————————【快速排序】· 学习笔记

还可以优化直接插入排序

  • 将数组分成两部分,前半部分有序,后半部分无序,不断地将无序区域的数字放入有序区域,插入的时候可以利用前半部分有序的特点,二分插入排序。例如如下过程:

在这里插入图片描述

在插入的时候,先通过二分查找确定要插入的位置,再进行插入即可。

  • 42
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
荷兰国旗问题是一个经典的排序问题,它要求按照荷兰国旗的颜色顺序(红、白、蓝)对一个包含红、白、蓝三种颜色的数组进行排序。 快速排序算法可以用来解决荷兰国旗问题。该算法基于治的思想,通过多次划和交换元素来达到排序的目的。以下是快速排序算法解决荷兰国旗问题的步骤: 1. 选择一个枢轴元素(一般是数组的最后一个元素)。 2. 初始化三个指针:low指向数组的起始位置,high指向数组的末尾位置,mid指向数组的起始位置。 3. 从头遍历数组,如果当前元素小于枢轴元素,则交换当前元素和mid指针指向的元素,并将mid指针后移一位。 4. 如果当前元素等于枢轴元素,则将high指针前移一位。 5. 如果当前元素大于枢轴元素,则交换当前元素和high指针指向的元素,并将high指针前移一位。 6. 重复步骤3到步骤5,直到low指针和high指针相遇为止。 7. 最后,将枢轴元素放在mid指针的位置上,这样数组就被成了三个部:小于枢轴元素的部、等于枢轴元素的部和大于枢轴元素的部。 8. 递归地对小于和大于枢轴元素的部进行排序。 以下是一个示例荷兰国旗问题的快速排序的实现(使用Python语言): ```python def dutch_flag_sort(arr): def swap(arr, i, j): arr[i], arr[j] = arr[j], arr[i] def quicksort(arr, low, high): if low < high: pivot = arr[high] mid = low for i in range(low, high): if arr[i] < pivot: swap(arr, i, mid) mid += 1 swap(arr, mid, high) quicksort(arr, low, mid - 1) quicksort(arr, mid + 1, high) quicksort(arr, 0, len(arr) - 1) return arr # 示例用法 arr = [2, 0, 2, 1, 1, 0] sorted_arr = dutch_flag_sort(arr) print(sorted_arr) ``` 上述示例代码会输出 `[0, 0, 1, 1, 2, 2]`,即按照荷兰国旗顺序排序的结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值