3.5节最优二叉查找树

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include<algorithm>
#define keytype int
using namespace std;

keytype Key[20]={4,5,6,7};//包含了n个键
float p[20]={3/8,3/8,1/8,1/8};//查找到每个键的概率
int R[20][20];//每一步为根节点选择的索引
float A[20][20];//平均查找时间

struct nodetype{
    keytype key;
    nodetype* left;
    nodetype* right;
};
typedef nodetype* node_pointer;



//算法3.8查找二叉树
void binsearchtree(node_pointer tree,keytype keyin,node_pointer &p)
{
    bool found=false;
    p=tree;
    while(!found)
    {
        if(p->key==keyin)
        {
            found=true;
        }
        else if(keyin < p->key)
            p=p->left;
        else
            p=p->right;
    }
}

//算法3.9最优二叉查找树
void optsearchtree(int n,const float p[],float& minavg)//p为搜索每个点的概率
{
    for(int i=0;i<n;i++)
    {
        A[i][i]=0;
        A[i][i+1]=p[i];
        R[i][i]=0;
        R[i][i+1]=i;
    }
    float sump=0;
    for(int i=0;i<n;i++)
        sump+=p[i];
    for(int diagonal=1;diagonal<n;diagonal++)
    {
        for(int i=1;i<=n-diagonal;i++)
        {
            int j=i+diagonal;
            A[i][j]=A[i][i-1]+A[i+1][j]+sump;
            R[i][j]=i;
            for(int k=i+1;k<=j-1;k++)
            {
                float temp=A[i][k-1]+A[k+1][j];
                if(temp<A[i][j])
                {
                    A[i][j]=temp+sump;
                    R[i][j]=k;
                }
            }
        }
    }
    minavg=A[0][n-1];
}

//算法3.10生成最优二叉查找树
node_pointer BuildOptTree(int i,int j)
{
    int k;
    node_pointer p;
    k=R[i][j];
    if(k==0)
        return NULL;
    else{
        p->key=Key[k];
        p->left=BuildOptTree(i,k-1);
        p->right=BuildOptTree(k+1,j);
        return p;
    }
}

int main()
{
    memset(R,0,sizeof(int));
    memset(A,0,sizeof(float));
    int n=5;
    float minavg;
    optsearchtree(n,p,minavg);
    node_pointer np=BuildOptTree(0,n-1);
    cout<<minavg<<endl;
    cout<<R[0][n-1]<<endl;
    cout<<np->key<<endl;
    return 0;
}

ps:程序有些bug,还没调处来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值