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 = new int [len];
int * b_max_temp = new int [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 = new int [min_count];
for ( int i = 0 ; i < min_count; i ++ )
b_min[i] = b_min_temp[i];
int * b_max = new int [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 = new int [len];
int * a_max_temp = new int [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 = new int [min_count];
for ( int i = 0 ; i < min_count; i ++ )
a_min[i] = a_min_temp[i];
int * a_max = new int [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 = new int [len];
int * b_max_temp = new int [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 = new int [min_count];
for ( int i = 0 ; i < min_count; i ++ )
b_min[i] = b_min_temp[i];
int * b_max = new int [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 = new int [len];
int * a_max_temp = new int [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 = new int [min_count];
for ( int i = 0 ; i < min_count; i ++ )
a_min[i] = a_min_temp[i];
int * a_max = new int [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;
}