您的位置:首页 > 其它

标题:利用动态规划求解最优二叉树

2015-09-06 19:50 357 查看

摘要:二叉查找书所要查找的目标出现的频率可能不一样,因此它们在二叉查找树上的位置不同,查找的代价也不同.

(1)基本思路:

[1]因为二叉查找树的左儿子一定要小于右儿子,这里用单词作为元素.首先按照首字母的顺序排序,当首字母相同时,按照字符串的长度排序。

[2]假设对于单词wLeft……wRight进行构建二叉查找树,设F[Left][Right]以该单词集合中某个单词为根的最小查找代价.则可以写出递归关系

F[Left[Right]=minNi=1(wi+F[Left][i−1]+F[i+1][Right]+∑i=LeftRightPi)

注意:其中pi是某个单词出现的概率.因为原问题的子集相对原来的根要深了一层.所以必须将所有查找概率加上一遍。

[3]按照常规方法以空间换时间,注意构建循环的顺序和求解矩阵时基本一致.

.

#include "stdafx.h"
#include "malloc.h"
#define N 7
#define Infinity 100
typedef struct wordstr* word;
typedef word Array
;
struct wordstr
{
char *name;
int size;
double P;
};

double sum(Array words,int Left,int Right)
{
double sum = 0;
for (int i  = Left;i<=Right;i++)
sum += words[i]->P;

return sum;

}
void BestTree(Array words,double cost[]
,int Lastchange[]
)
{

int Left,Right,cutoff,i;
double Thiscost;
for (Left = 0;Left<=N-1;Left++)
{
cost[Left][Left] = words[Left]->P;
Lastchange[Left][Left] = Left;
}
for(cutoff = 1;cutoff<=N-1;cutoff++)
{
for(Left = 0;Left<=N-1-cutoff;Left++)
{
Right = Left + cutoff;
cost[Left][Right] = Infinity;
for(i = Left;i<=Right;i++)
{
if(i-1<Left)
cost[Left][i-1] = 0;//注意特殊情况,没有左子树
if(i+1>Right)
cost[i+1][Right] = 0;
Thiscost = (cost[Left][i-1]+cost[i+1][Right]+ sum(words,Left,Right));
if (Thiscost < cost[Left][Right])
{
cost[Left][Right] = Thiscost;
Lastchange[Left][Right] = i;//记录相应的根
}
}
}
}
}
void PrintTree(int Lastchange[]
,int Left,int Right)
{
//将树打印一遍
if(Left == Right)
{
printf("%d ",Left);
}
else if (Left < Right)
{

int k =Lastchange[Left][Right];
printf("%d ",k);
PrintTree(Lastchange,Left,k-1);
PrintTree(Lastchange,k+1,Right);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划 二叉树