一、荷兰国旗问题

问题描述:

给定一个数组和一个数num,将小于num的数放在数组的左边,大于num的数放在数组的右边组成一个新数组

 解决方法:

将数组分为三个区域,分别是less区域,等于num区域和more区域,然后从做到右遍历数组元素,大于num的数放到less区域,等于num区域的数不动,大于num的数放进more区域

csdn富文本编辑区下面这块区域不知道怎么删掉[捂脸]

 

具体步骤: 

1、如下图所示,less = L-1,current从L开始,more = R+1.

荷兰国旗问题和改进的快排问题

 

2、如果current下标对应的元素小于num则将该元素和less的下一个数交换,然后less++(less区域增加一个元素),current++

           荷兰国旗问题和改进的快排问题

3、 如果current下标对应的元素和num相等,less和more区域不发生改变,current++,继续考察下一个元素

                  荷兰国旗问题和改进的快排问题

4、如果current下标对应的元素要比num大,则将该元素和more的前一个数交换,more--(more区域增加一个元素),current不动,继续考察这个数(因为more前面这个数和num的关系未知)

                          荷兰国旗问题和改进的快排问题

                  

 实现代码:

#include<iostream>
using namespace std;

void swap(int arr[], int i, int j)
{
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}
int* partition(int arr[], int L, int R, int num)
{
	int less = L - 1;
	int more = R + 1;
	int current = L;
	while (current < more)
	{
		//小于num的值将++less的位置和current的位置互换,current++
		if (arr[current] < num)
			swap(arr, ++less, current++);
		//大于more的值将--more的位置和current的位置互换,current不动,继续考察当前元素! 
		else if (arr[current] > num)
			swap(arr, --more, current);
		//等于num的位置不动,current指向下一个位置
		else
			current++;
	}
	//返回最后重新排序的数组
	int p1_length = R - L + 1;
	int *p1 = new int[p1_length];
	for (int i = 0; i < p1_length; i++)
		p1[i] = arr[i];
	/*//将最后等于current两端边界的位置存入数组返回了
	int *p2 = new int[2]{less + 1,more - 1};*/
	return p1;
}
int main()
{
	int a[] = {4,7,6,3,2,5,5};
	int a_length = sizeof(a) / sizeof(a[0]);
	int *p = partition(a, 0, a_length-1,5);
	//求动态数组的大小使用_misze(arr)/sizeof(arr[0])
	//cout << (int)_msize(p) / (int)sizeof(p[0]) << endl;
	for (int i = 0; i < ((int)_msize(p) / (int)sizeof(p[0])); i++)
		cout << p[i]<<" ";
	cout << endl;//输出 4 3 2 5 5 6 7 
	system("pause");
}

二、改进的快排问题

大致思路:

1、取出数组中的最后一个元素作为上述荷兰国旗的num进行判断并返回等于num的左右边界p[0]和p[1],这样我们就得到了分别具有小于num,等于num和大于num的三个区域

2、等于num的区域不用动,在小于num的区域[L,p[0]-1]和大于num的区域[p[1]+1,R]中重复操作步骤1。也就是,在小于num的区域中取出最后一个元素作为这个区域的num使用荷兰国旗问题递归求解,大于num的区域同理。

具体步骤图解:

荷兰国旗问题和改进的快排问题

代码实现:

#include<iostream>
using namespace std;

void swap(int arr[], int i, int j)
{
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}
int* partition(int arr[], int L, int R)
{
	int less = L - 1;
	int more = R;
	while (L< more)
	{
		if (arr[L] < arr[R])
			swap(arr, ++less, L++);
		else if (arr[L] >arr[R])
			swap(arr, --more, L);
		else
			L++;
	}
	swap(arr, more, R);
	int *p= new int[2]{ less + 1,more - 1 };
	return p;
}
int* quickSort(int arr[], int L, int R)
{
	if (L < R)
	{
		int *p = partition(arr, L, R);
		quickSort(arr, L, p[0]-1);
		quickSort(arr, p[1] + 1, R);
	}
	int *p = new int[R - L + 1];
	for (int i = 0; i < R - L + 1; i++)
		p[i] = arr[i];
	return p;
}
int main()
{
	int a[] = { 4,7,6,3,2,5,5 };
	int a_length = sizeof(a) / sizeof(a[0]);
	int *p = quickSort(a,0, a_length-1);
	//求动态数组的大小使用_misze(arr)/sizeof(arr[0])
	//cout << (int)_msize(p) / (int)sizeof(p[0]) << endl;
	for (int i = 0; i < ((int)_msize(p) / (int)sizeof(p[0])); i++)
		cout << p[i] << " ";
	cout << endl;//输出 2 3 4 5 5 6 7
	system("pause");
}

 

相关文章:

  • 2021-04-01
  • 2021-07-06
  • 2021-08-03
  • 2021-09-28
  • 2022-12-23
  • 2021-08-31
猜你喜欢
  • 2021-11-19
  • 2021-10-05
  • 2021-11-01
相关资源
相似解决方案