--------------------------------------------------------------------------------------------------------------------------------
代码:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
typedef struct TreeNode{
char data;
int weight;
struct TreeNode *lchild,*rchild;
}TreeNode;
//初始化二叉树
void init_tree(TreeNode *root){
root=NULL;
printf("初始化成功!\n");
}
//构造次优查找树 1 9
TreeNode *SecondOptimal(TreeNode *root,char R[],int sw[],int low,int high){
//由有序表 R[low...high]及其累计权值表 sw(其中 sw[0]==0)递归构造次优查找树 T
int i=low;
double min=fabs(sw[high]-sw[low]); //求绝对值
int dw=sw[high]+sw[low-1];
int j;
for(j=low+1;j<=high;++j){ //选择最小的 △Pi值
if(fabs( dw- sw[j] - sw[j-1] ) < min ){
i=j;
min=fabs(dw-sw[j]-sw[j-1]);
}
}
root=(TreeNode *)malloc(sizeof(TreeNode));
root->data=R[i]; //生成结点
if(i==low)
root->lchild=NULL; //左子树为空
else
root->lchild=SecondOptimal(root->lchild,R,sw,low,i-1); //构造左子树
if(i==high) //右子树为空
root->rchild=NULL;
else
root->rchild=SecondOptimal(root->rchild,R,sw,i+1,high); //构造右子树
return root;
}
//前序遍历
void pre_order(TreeNode *root)
{
if(root)
{
putchar(root->data);
pre_order(root->lchild);
pre_order(root->rchild);
}
}
//中序遍历
void in_order(TreeNode *root)
{
if(root)
{
in_order(root->lchild);
putchar(root->data);
in_order(root->rchild);
}
}
//后序遍历
void post_order(TreeNode *root)
{
if(root)
{
post_order(root->lchild);
post_order(root->rchild);
putchar(root->data);
}
}
//查找二叉树是否存在某元素
int search_tree(TreeNode *root,char key){
if(root==NULL) //若次优查找树为空,则查找不成功
return 0;
else{ //否则
if(root->data==key){ //首先将给定值 key 和其根结点的关键字进行比较
return 1; //若相等,则查找成功
}
else{
if(search_tree(root->lchild,key) || search_tree(root->rchild,key))
return 1; //再根据给定值 key 小于或大于根结点的关键字而分别在左右子树查找,直至成功
else //或者不成功
return 0;
}
}
}
//主函数
void main(){
TreeNode *root;
int low=1,high=10;
int *weight,*sw;
char *R;
int i,j;
char ch;
init_tree(root);
R=(char *)malloc(high*sizeof(char));
for(i=low;i<high;i++)
R[i]='A'+i-1;
printf("构造次优查找树的点R[]:\n");
for(i=low;i<high;i++)
printf("%-5c",R[i]); //产生九个字母
printf("\n");
weight=(int *)malloc(high*sizeof(int));
weight[0]=0;
weight[1]=1;
weight[2]=1;
weight[3]=2;
weight[4]=5;
weight[5]=3;
weight[6]=4;
weight[7]=4;
weight[8]=3;
weight[9]=5;
printf("构造次优查找树额权值weight[]:\n");
for(i=low;i<high;i++)
printf("%-5d",weight[i]);
printf("\n");
sw=(int *)malloc(high*sizeof(int));
sw[0]=0;
for(i=low;i<high;i++)
sw[i]=sw[i-1]+weight[i];
printf("构造次优查找树的点累计权值sw[]\n");
for(i=low;i<high;i++)
printf("%-5d",sw[i]);
//创建次优查找树
root=SecondOptimal(root,R,sw,low,high-1); //high 为 10
printf("\n前序遍历序列是:\n");
pre_order(root);
printf("\n");
printf("中序遍历序列是:\n");
in_order(root);
printf("\n");
printf("后序遍历序列是:\n");
post_order(root);
printf("\n");
printf("输入要查找的元素!\n");
scanf("%c",&ch);
if(search_tree(root,ch) == 1)
printf("yes!\n");
else
printf("no!\n");
}
代码转载自:http://blog.csdn.net/wangyunyun00/article/details/38056933
总结:大量的实验研究表明,次优查找树和最优查找树的查找性能只差仅为 1%-2%,很少超过 3%,而且构造次优查找树的算法的时间复杂度为 O(n lon n).因此上述算法是构造近似最优二叉查找树的有效算法。