CLRS 8-4 :水壶比较问题
解答:
a)两个for循环即可,O(n^2);
b)不会证明,略;
c)算法思想:
1.由于相同颜色的瓶子不能比较,因而不能对红色瓶子或者蓝色瓶子进行内部排序。
2.随机从红色瓶子抽取一个瓶子(实现时选的是中间瓶子),然后与蓝色瓶子进行比较,找到那个相等的蓝色瓶子,它们就是配对的,小于这个红色瓶子的就存在一个数组内,大于这个红色瓶子的就存在另外一个数组内,用得到的蓝色瓶子再和红色瓶子组进行比较,将小于这个蓝色瓶子的存在一个数组内,大于这个蓝色瓶子的存在另一个数组内。
3.对得到的两组小的红色瓶子和蓝色瓶子重复2过程,对得到的两组大的红色瓶子和蓝色瓶子重复2过程,即递归。
代码写的比较邋遢,跟快排相似。
#include <iostream>
using namespace std;
void match(int a[], int b[], int len);
#define MAX 1000000
int main()
{
//两个数组内部是不能相互进行比较排序的
int a[] = {2, 3, 7, 5, 1, 9, 6, 8, 4};
int b[] = {4, 7, 9, 5, 1, 3, 8, 2, 6};
match(a, b, 9);
return 0;
}
void match(int a[], int b[], int len)
{
if(len <1)
return;
int middle = len/2;
int* b_min_temp =newint[len];
int* b_max_temp =newint[len];
for(int i =0; i < len; i++)
{
b_min_temp[i] = MAX;
b_max_temp[i] = MAX;
}
int min_count =0;
int max_count =0;
for(int i =0; i < len; i++)
{
if(b[i] < a[middle])
{
b_min_temp[min_count] = b[i];
min_count++;
}
else if(b[i] > a[middle])
{
b_max_temp[max_count] = b[i];
max_count++;
}
else
{
cout<<"["<<a[middle]<<", "<<b[i]<<"]"<<endl;
}
}
//b_min保存小于a[middle]的数
//b_max保存大于a[middle]的数
int* b_min =newint[min_count];
for(int i =0; i < min_count; i++)
b_min[i] = b_min_temp[i];
int* b_max =newint[max_count];
for(int i =0; i < max_count; i++)
b_max[i] = b_max_temp[i];
delete[] b_min_temp;
delete[] b_max_temp;
/**************************************************************************************************************************/
//这两段代码相同,可以用一个函数来包含这段代码,在这就省了。
int* a_min_temp =newint[len];
int* a_max_temp =newint[len];
for(int i =0; i < len; i++)
{
a_min_temp[i] = MAX;
a_max_temp[i] = MAX;
}
min_count =0;
max_count =0;
//注意这里用的是a[middle],并不是拿红瓶和红瓶比,其实这里的a[middle]指代的是找到的b[i]这个蓝瓶,然后用这个蓝瓶来跟a数组比较
for(int i =0; i < len; i++)
{
if(a[i] < a[middle])
{
a_min_temp[min_count] = a[i];
min_count++;
}
else if(a[i] > a[middle])
{
a_max_temp[max_count] = a[i];
max_count++;
}
}
//a_min保存小于a[middle]的数
//a_max保存大于a[middle]的数
int* a_min =newint[min_count];
for(int i =0; i < min_count; i++)
a_min[i] = a_min_temp[i];
int* a_max =newint[max_count];
for(int i =0; i < max_count; i++)
a_max[i] = a_max_temp[i];
delete[] a_min_temp;
delete[] a_max_temp;
match(a_min, b_min, min_count);
delete[] a_min;
delete[] b_min;
match(b_max, b_max, max_count);
delete[] a_max;
delete[] b_max;
}
using namespace std;
void match(int a[], int b[], int len);
#define MAX 1000000
int main()
{
//两个数组内部是不能相互进行比较排序的
int a[] = {2, 3, 7, 5, 1, 9, 6, 8, 4};
int b[] = {4, 7, 9, 5, 1, 3, 8, 2, 6};
match(a, b, 9);
return 0;
}
void match(int a[], int b[], int len)
{
if(len <1)
return;
int middle = len/2;
int* b_min_temp =newint[len];
int* b_max_temp =newint[len];
for(int i =0; i < len; i++)
{
b_min_temp[i] = MAX;
b_max_temp[i] = MAX;
}
int min_count =0;
int max_count =0;
for(int i =0; i < len; i++)
{
if(b[i] < a[middle])
{
b_min_temp[min_count] = b[i];
min_count++;
}
else if(b[i] > a[middle])
{
b_max_temp[max_count] = b[i];
max_count++;
}
else
{
cout<<"["<<a[middle]<<", "<<b[i]<<"]"<<endl;
}
}
//b_min保存小于a[middle]的数
//b_max保存大于a[middle]的数
int* b_min =newint[min_count];
for(int i =0; i < min_count; i++)
b_min[i] = b_min_temp[i];
int* b_max =newint[max_count];
for(int i =0; i < max_count; i++)
b_max[i] = b_max_temp[i];
delete[] b_min_temp;
delete[] b_max_temp;
/**************************************************************************************************************************/
//这两段代码相同,可以用一个函数来包含这段代码,在这就省了。
int* a_min_temp =newint[len];
int* a_max_temp =newint[len];
for(int i =0; i < len; i++)
{
a_min_temp[i] = MAX;
a_max_temp[i] = MAX;
}
min_count =0;
max_count =0;
//注意这里用的是a[middle],并不是拿红瓶和红瓶比,其实这里的a[middle]指代的是找到的b[i]这个蓝瓶,然后用这个蓝瓶来跟a数组比较
for(int i =0; i < len; i++)
{
if(a[i] < a[middle])
{
a_min_temp[min_count] = a[i];
min_count++;
}
else if(a[i] > a[middle])
{
a_max_temp[max_count] = a[i];
max_count++;
}
}
//a_min保存小于a[middle]的数
//a_max保存大于a[middle]的数
int* a_min =newint[min_count];
for(int i =0; i < min_count; i++)
a_min[i] = a_min_temp[i];
int* a_max =newint[max_count];
for(int i =0; i < max_count; i++)
a_max[i] = a_max_temp[i];
delete[] a_min_temp;
delete[] a_max_temp;
match(a_min, b_min, min_count);
delete[] a_min;
delete[] b_min;
match(b_max, b_max, max_count);
delete[] a_max;
delete[] b_max;
}