// zuiyousousuoerchashu.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<iostream> using namespace std; double p[] = { 0,0.15,0.1,0.05,0.10,0.2 }; double q[] = { 0.05,0.10,0.05,0.05,0.05,0.10}; double e[7][7], w[7][7]; int root[7][7]; void option(int n) //求最优搜索二叉树 { for (int i = 1; i <= n + 1; i++) { e[i][i - 1] = q[i - 1]; //j=i-1,则节点左边为空,此时为伪关键字d(i-1) w[i][i - 1] = q[i - 1]; //w为搜索代价增量 } for (int l = 1; l <= n; l++) { //自底向上地计算间隔为1,2,3..个节点时的最优父节点,l为间隔量 for (int i = 1; i <= n - l + 1; i++) { //i为起点 int j = i + l - 1; //j为每一段的终点 e[i][j] = 65535; //先设置为一个较大的树 w[i][j] = w[i][j - 1] + p[j] + q[j]; //利用递归式计算w的值 for (int r = i; r <= j; r++) { //此循环从[i,j]中找出使代价最小的最优节点作为父节点,w[i][j]已由上步算出 double t = e[i][r - 1] + e[r + 1][j] + w[i][j]; if (t < e[i][j]) { e[i][j] = t; root[i][j] = r; } } } } } void construct(int i, int j) //重建最优二叉树,先递归左子树的节点,再递归右子树的节点 { if (i <= j) { int r = root[i][j]; cout << r <<endl; construct(i, r - 1); construct(r+1,j); } } void construct2(int i, int j) //重建最优二叉树,分三种情况 { if(i==1&&j==5) cout << "k" << root[1][5] << "是根" << endl; if (i < j) { int r = root[i][j]; if (i != r) cout << "k" << root[i][r - 1] << "是k" << r << "的左孩子"<<endl; construct2(i, r - 1); //先递归左子树 if (j != r) cout << "k" << root[r + 1][j] << "是k" << r << "的右孩子" << endl; construct2(r+1,j); //后递归右子树 } if (i == j) //i=j时,此时该节点有两个伪关键字作为子节点 { cout<<"d"<<i-1<<"是k"<<i<< "的左孩子" << endl; cout << "d" << i<< "是k" << i << "的右孩子" << endl; } if (i > j) //i>j时,该节点右边没有关键字,因此右边有一个伪关键字子节点 { cout << "d" << j << "是k" << j << "的右孩子" << endl; } } int main() { option(5); //construct(1, 5); construct2(1, 5); while (1); return 0; }