荷兰国旗问题、快速排序

目录

一.荷兰国旗

二.快速排序(乱序快排优化版)

三.应用传统快排求中位数


一.荷兰国旗

1.题目描述

给定一个数组arr和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。

要求额外空间复杂度为O(1),时间复杂度为O(N)。

2.分析思路

初始化less=-1,more=len(arr),当前位置为cur=0。

设该过程为partition。设数组为(arr,l,r),0~less为小于num区域,more右为大于等于num区域。

循环结束的条件,cur碰上num。如图1。

(1)cur<num,当前数和小于区域下一个数交换,小于区域扩下个位置。cur跳下一个。

swap(arr, ++less, l++);

(2)cur=num,cur直接跳下一个。

cur++;

(3)cur>num,和大于区域前一个数交换,大于区域向左扩一个位置。cur停在原地(当前数不变)。

swap(arr, --more, cur);

3.实现代码

vector<int> partition(vector<int> &arr,int L ,int R,int,num) {
	int less = L- 1;
	int more = R+1;
	int cur=L;
	while (cur < more) {
		if (arr[cur] < num) {
			swap(arr[++less], arr[L++]);
		else if (arr1[cur] > num) {
			swap(arr[more--],arr[L]);
		}
		else {
			cur++;
		}

	}
	vector<int> p(2);
	p[0] = less + 1;   //less+1等于区域第一个数
	p[1] = more-1;    //more-1等于区域最后一个数
	return p;  //返回等于区域下标
}

二.快速排序(乱序快排优化版)

1.算法思想

采用分治的思想

  • 先从数组中取最后一个数作为基准数。
  • 分区过程,将比这个数大的数全放到它的右边,小于它的数全放到它的左边,等于它的放中间。
  • 再对小于和大于的左右区间重复第二步,递归结束的条件是L>R。  

2.时间复杂度O(N*logN),额外空间复度O(logN),算法不稳定

3.实现代码

void quickSort(vector<int> arr) {
	if (arr.empty() || arr.size() < 2) {
		return;
		}
		quickSort(arr, 0, arr.size()- 1);
	}

void quickSort(vector<int> arr, int l, int r) {
	if (l < r) {
		swap(arr, l + (int) (Math.random() * (r - l + 1)), r);  
        //快排中比较的最后一个数随机按概率定
		vector<int> p = partition(arr, l, r);
		quickSort(arr, l, p[0] - 1);  //小于区域递归排序
		quickSort(arr, p[1] + 1, r);  //大于区域递归排序
	}

vector<int> partition(vector<int> &arr,int L ,int R) {
	int less = L- 1;
	int more = R;
	while (L < more) {
		if (arr[L] < arr[r]) {
			swap(arr[++less], arr[L++]);
		}
		else if (arr1[L] > arr[r]) {
			swap(arr[more--],arr[L]);
		}
		else {
			L++;
		}

	}
	swap(arr[more],arr[r]);  //使最右边的数放到等于区域
	vector<int> p(2);
	p[0] = less + 1;   //less+1等于区域第一个数
	p[1] = more-1;    //more-1等于区域最后一个数
	return p;  //返回等于区域下标
}

补充:

  • 1.swap(arr[more],arr[r]);的原理如图2.
  • 2.传统快排如果打偏,算法复杂度O(N2)

三.应用传统快排求中位数

荷兰国旗问题是一个经典的排序问题,它要求按照荷兰国旗的颜色顺序(红、白、蓝)对一个包含红、白、蓝三种颜色的数组进行排序。 快速排序算法可以用来解决荷兰国旗问题。该算法基于分治的思想,通过多次划分和交换元素来达到排序的目的。以下是快速排序算法解决荷兰国旗问题的步骤: 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]`,即按照荷兰国旗顺序排序的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值