学习第九章查找的时候,看到了次优查找树。次优查找树的用途是什么呢?
若对有序表的查找是在等概率的条件下进行的,则在查找过程中可以使用二分查找(折半查找),其性能最优。如果在不等概率的条件下进行查找呢?这时候折半查找的效率就不一定是最高的,因此可以构造一种二叉树使得其查找效率最高。称为静态最优查找树(Static Optimal Search Tree),但构造最优查找树花费的时间代价较高,因此寻找一种近似最优查找树的方法,使其带权内路径长度在所有具有同样权值的二叉树中近似(注意近似两个字)为最小,称这类二叉树为次优二叉树。
在此,不得不说我不懂得次优查找树的构造原理,希望有懂的的人能讲解一下。我只是根据书上的代码,实现了次优二叉树的构造,下面是代码,仅供大家参考。
#include<stdio.h>
#include<malloc.h>
#include<math.h>
typedef struct //结点中存储关键字信息和权值
{
char key;
int weight;
}ElemType;
typedef struct BiTNode //树的存储结构
{
ElemType data;
BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
void InitBiTree(BiTree &T) //初始化树
{
T=NULL;
}
void InOrderTraverse(BiTree T)//中序输出该树
{
if(T)
{
InOrderTraverse(T->lchild);
printf("(%c,%d)",T->data.key,T->data.weight);
InOrderTraverse(T->rchild);
}
}
int SecondOptimal(BiTree &T,ElemType R[],float sw[],int low,int high)
{
int i=low,j;
float dw=sw[low-1]+sw[high];
float min=dw;
for(j=i+1;j<=high;j++)
if(abs(dw-sw[j]-sw[j-1])<min)
{
i=j;
min=abs(dw-sw[j]-sw[j-1]);
}
if(!(T=(BiTree)malloc(sizeof(BiTNode))))
return 0;
T->data=R[i-1]; //注意在主函数中,用了R[0],所以次处下表应减1
if(i==low)
T->lchild=NULL;
else
SecondOptimal(T->lchild,R,sw,low,i-1);
if(i==high)
T->rchild=NULL;
else
SecondOptimal(T->rchild,R,sw,i+1,high);
return 1;
}
int main()
{
BiTree T;
InitBiTree(T);
ElemType R[9];
int i;
for(i=0;i<9;i++)
R[i].key=(char)('a'+i);
R[0].weight=1;
R[1].weight=1;
R[2].weight=2;
R[3].weight=5;
R[4].weight=3;
R[5].weight=4;
R[6].weight=4;
R[7].weight=3;
R[8].weight=5;
float sw[10];
sw[0]=0;
for(i=1;i<10;i++) //计算sw的值
sw[i]=R[i-1].weight+sw[i-1];
SecondOptimal(T,R,sw,1,9);
InOrderTraverse(T);
return 0;
}