• 次优二叉树


      在有序序列的查找中,如果各个元素的查找概率都是一样的,那么二分查找是最快的查找算法,但是如果查找元素的查找概率是不一样的,那么用二分查找就不一定是最快的查找方法了,可以通过计算ASL来得知。所以基于这种查找元素概率不想等的有序序列,可以通过构造最优二叉树的方法,使得该二叉树的带权路径长度最小,这样的二叉树的构造代价是非常大的,所以用一种近似的算法,构造次优查找树,该树的带权路径长度近似达到最小。

      数据结构中算法描述为:

      

      1 #include <iostream>
      2 #include <cmath>
      3 #include <cstdlib>
      4 #include <iomanip>
      5 
      6 using namespace std;
      7 
      8 typedef struct treenode
      9 {
     10     char data;
     11     int weight;
     12     treenode *left;
     13     treenode *right;
     14 }Treenode,*Treep;
     15 
     16 //初始化二叉树
     17 void init_tree(Treep &root)
     18 {
     19     root=NULL;
     20     cout<<"初始化成功!"<<endl;
     21 }
     22 
     23 //创建二叉树
     24 void SecondOptimal(Treep &rt, char R[],int sw[], int low, int high)
     25 {
     26     //由有序表R[low....high]及其累积权值表sw(其中sw[0]==0)递归构造次优查找树T
     27     int i = low;
     28     //int min = abs(sw[high] - sw[low]);
     29     int dw = sw[high] - sw[low-1];
     30     int min = dw;
     31     for(int j=low+1; j<=high; ++j)        //选择最小的ΔPi值
     32     {
     33         if(abs(dw-sw[j]-sw[j-1]) < min)
     34         {
     35             i=j;
     36             min=abs(dw-sw[j]-sw[j-1]);
     37         }
     38     }
     39     rt=new Treenode;
     40     rt->data=R[i];        //生成节点
     41     if(i==low)            //左子树为空
     42         rt->left = NULL;
     43     else                //构造左子树
     44         SecondOptimal(rt->left, R, sw, low, i-1);
     45 
     46     if(i==high)            //右子树为空
     47         rt->right = NULL;
     48     else                //构造右子树
     49         SecondOptimal(rt->right, R, sw, i+1, high);
     50 }//SecondOptimal
     51 
     52 //前序遍历二叉树
     53 void pre_order(Treep rt)
     54 {
     55     if(rt)
     56     {
     57         cout<<rt->data<<"  ";
     58         pre_order(rt->left);
     59         pre_order(rt->right);
     60     }
     61 }
     62 
     63 //中序遍历二叉树
     64 void in_order(Treep rt)
     65 {
     66     if(rt)
     67     {
     68         in_order(rt->left);
     69         cout<<rt->data<<"  ";
     70         in_order(rt->right);
     71     }
     72 }
     73 
     74 //后序遍历二叉树
     75 void post_order(Treep rt)
     76 {
     77     if(rt)
     78     {
     79         post_order(rt->left);
     80         post_order(rt->right);
     81         cout<<rt->data<<"  ";
     82     }
     83 }
     84 
     85 //查找二叉树中是否存在某元素
     86 int seach_tree(Treep &rt,char key)
     87 {
     88     if(rt==NULL) 
     89         return 0; 
     90     else 
     91     { 
     92         if(rt->data==key) 
     93         {
     94             return 1;
     95         }
     96         else
     97         {
     98             if(seach_tree(rt->left,key) || seach_tree(rt->right,key))
     99                 return 1;    //如果左右子树有一个搜索到,就返回1
    100             else
    101                 return 0;    //如果左右子树都没有搜索到,返回0
    102         }
    103     }
    104 }
    105 
    106 int main()
    107 {
    108     Treep root;
    109     init_tree(root);        //初始化树
    110     int low=1, high=10;
    111     int *weight, *sw;
    112     char *R;
    113     
    114     R=new char[high];
    115     for(int i=low; i<high; i++)
    116         R[i]='A'+i-1;
    117     cout<<"构造次优查找树的点R[]:"<<endl;
    118     for(int i=low; i<high; i++)
    119         cout<<setw(3)<<R[i]<<"  ";
    120     cout<<endl;
    121     
    122     weight=new int[high];
    123     weight[0]=0;
    124     weight[1]=1;
    125     weight[2]=1;
    126     weight[3]=2;
    127     weight[4]=5;
    128     weight[5]=3;
    129     weight[6]=4;
    130     weight[7]=4;
    131     weight[8]=3;
    132     weight[9]=5;
    133     cout<<"构造次优查找树的点的权值weight[]:"<<endl;
    134     for(int i=low; i<high; i++)
    135         cout<<setw(3)<<weight[i]<<"  ";
    136     cout<<endl;
    137         
    138     sw=new int[high];
    139     sw[0]=0;
    140     for(int i=low; i<high; i++)
    141     {
    142         sw[i]=sw[i-1]+weight[i];
    143     }
    144     cout<<"构造次优查找树的点累积权值sw[]:"<<endl;
    145     for(int i=low; i<high; i++)
    146         cout<<setw(3)<<sw[i]<<"  ";
    147     cout<<endl;
    148         
    149     //创建二叉树
    150     SecondOptimal(root, R, sw, low, high-1);
    151     
    152     cout<<"前序遍历序列是:"<<endl;
    153     pre_order(root);
    154     cout<<endl;
    155     
    156     cout<<"中序遍历序列是:"<<endl;
    157     in_order(root);
    158     cout<<endl;
    159 
    160     cout<<"后序遍历序列是:"<<endl;
    161     post_order(root);
    162     cout<<endl;
    163 
    164     //查找二叉树中是否存在某元素
    165     cout<<"输入要查找的元素!"<<endl;
    166     char ch;
    167     cin>>ch;
    168     if(seach_tree(root,ch)==1)
    169         cout<<"Yes"<<endl;
    170     else
    171         cout<<"No"<<endl;
    172     while(1);
    173     return 0;
    174 }

      运行结果如下:
      

  • 相关阅读:
    CSS盒子模型
    getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
    MYSQL中的CASE WHEN END AS
    单点登录的精华总结
    git&github
    June 21st 2017 Week 25th Wednesday
    June 20th 2017 Week 25th Tuesday
    June 19th 2017 Week 25th Monday
    June 18th 2017 Week 25th Sunday
    June 17th 2017 Week 24th Saturday
  • 原文地址:https://www.cnblogs.com/hxsyl/p/3103288.html
Copyright © 2020-2023  润新知