最优二叉查找树
问题描述:对于给定的一组改路,构造一个期望搜索代价最小的二叉查找树。
《算法导论》第二版213页。
源程序:
#include <iostream>
#include <vector>
using namespace std;
#define KEY_NUMBER 5
#define INFINITY 1000
//期望搜索代价,只使用1<=i<=n+1,0<=j<=n的表项
// 其中expected_cost[i,i-1]表示i为根的搜索树的期望搜索代价,该搜索树只包含虚拟键d[i-1]
float expected_cost[KEY_NUMBER + 2][KEY_NUMBER + 2];
//只使用1<=i<=j<=n的表项
int root[KEY_NUMBER + 1][KEY_NUMBER + 1];
//概率和数组
float w[KEY_NUMBER + 2][KEY_NUMBER + 2];
/*
*先根遍历最优二叉查找树
* start: 待遍历的子树的起始关键字
* end:待遍历的子树的结束关键字
* mid:待遍历的子树的树根对应的关键字
* leaf_index:下一个访问的虚拟键下标
*/
void ConstructRecursively(int start,int end,int mid,int& leaf_index)
{
if(start == mid)
{
cout << "d[" << leaf_index << "]是k[" << mid << "]左孩子" << endl;
leaf_index ++;
if(mid == end)
{
cout << "d[" << leaf_index << "]是k[" << mid << "]右孩子" << endl;
leaf_index ++;
}
else
{
int right_child = root[mid + 1][end];
cout << "k[" << right_child << "]是k[" << mid << "]右孩子" << endl;
ConstructRecursively(mid + 1,end,right_child,leaf_index);
}
}
else
{
int left_child = root[start][mid - 1];
cout << "k[" << left_child << "]是k[" << mid << "]左孩子" << endl;
ConstructRecursively(start,mid - 1,left_child,leaf_index);
if(mid == end)
{
cout << "d[" << leaf_index << "]是k[" << mid << "]右孩子" << endl;
leaf_index ++;
}
else
{
int right_child = root[mid + 1][end];
cout << "k[" << right_child << "]是k[" << mid << "]右孩子" << endl;
ConstructRecursively(mid + 1,end,right_child,leaf_index);
}
}
}
void Construct(int n)
{
int root_index = root[1][n];
cout << "k[" << root_index << "]是根" << endl;
int leaf_index = 0;
ConstructRecursively(1,n,root_index,leaf_index);
}
void OptimalSearch(float *p,float *q,int n)
{
//初始化
for(int i = 1;i <= n + 1;++ i)
{
expected_cost[i][i - 1] = q[i - 1];
w[i][i - 1] = q[i - 1];
}
for(int len = 1;len <= n;++ len)
{
for(int i = 1;i <= n + 1 - len;++ i)
{
int j = i + len - 1;
expected_cost[i][j] = INFINITY;
w[i][j] = w[i][j - 1] + q[j] + p[j];
for(int k = i;k <= j;++ k)
{
double cost = expected_cost[i][k - 1] + expected_cost[k + 1][j] + w[i][j];
if(cost < expected_cost[i][j])
{
expected_cost[i][j] = cost;
root[i][j] = k;
}
}
}
}
}
int main()
{
float p[6] = {0,0.15,0.10,0.05,0.10,0.20};
float q[6] = {0.05,0.10,0.05,0.05,0.05,0.10};
OptimalSearch(p,q,5);
Construct(5);
return 0;
}
看来看去,还是算法导论写得好~~
内心柔软,技术要强硬。