![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
// 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;
}