一、荷兰国旗问题
问题描述:
给定一个数组和一个数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");
}