第九章:查找(2)次优查找树的递归算法



--------------------------------------------------------------------------------------------------------------------------------

代码:

#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).因此上述算法是构造近似最优二叉查找树的有效算法。

猜你喜欢

转载自blog.csdn.net/qq_40191710/article/details/79623993