二叉排序(查找)树

[复制链接]
 楼主| programmable 发表于 2019-9-14 18:27 | 显示全部楼层 |阅读模式
1.定义
     二叉排序树(Binary Search Tree)又称二叉搜索(查找)树,其定义如下:
    (1)若它的左子树非空,则左子树上所有结点的权值都比根结点的权值小;
    (2)若它的右子数非空,则右子树上所有结点的权值都比根结点的权值大;
    (3)左、右子树本身又是一棵二叉排序树。
以上既是二叉排序树的定义,同时也是它的性质。从定义可以看出,二叉排序树的定义是一个递归的定义。对于一棵二叉排序树的中序遍历则是一个递增有序序列。

 楼主| programmable 发表于 2019-9-14 18:28 | 显示全部楼层
2.二叉排序树的插入Insert

   根据二叉排序树的递归定义,进行插入操作的时候可以用递归实现,其插入过程如下:

   (1)如果二叉排序树为空,则创建一个关键字为key的结点,并将其作为根结点;

   (2)否则将key和根结点的key值比较,若相等则返回;

       1)若key值小于根结点的key值,判断根结点的左孩子是否为空,如果为空,则创建一个关键字为key的结点,并将该结点作为根结点的

         左孩子;如果不为空,则递归插入到该根结点的左子树当中。

       2)若key值大于根结点的key值,判断根结点的右孩子是否为空,如果为空,则创建一个关键字为key的结点,并将该结点作为根结点的

         右孩子;如果不为空,则递归插入到该根结点的右子树当中。
 楼主| programmable 发表于 2019-9-14 18:28 | 显示全部楼层
递归实现:

  1. void insert(BSTNode *&root,ElemType key)      //注意这里为什么用指针的引用
  2. {
  3.     if(root==NULL)                //如果该树为空
  4.     {
  5.         root=(BSTNode *)malloc(sizeof(BSTNode));
  6.         root->key=key;
  7.         root->left=NULL;
  8.         root->right=NULL;
  9.     }
  10.     else
  11.     {
  12.         if(root->key==key)
  13.             return;
  14.         else if(root->key>key)   //key小于根结点的权值
  15.         {
  16.             if(root->left==NULL)    //root的左孩子为空,则创建一个结点作为root的左孩子
  17.             {
  18.                 BSTNode *p=(BSTNode *)malloc(sizeof(BSTNode));
  19.                 p->key=key;
  20.                 p->left=NULL;
  21.                 p->right=NULL;
  22.                 root->left=p;
  23.             }
  24.             else
  25.                 insert(root->left,key);   //递归插入到左子树中
  26.         }
  27.         else                     //key大于根结点的权值
  28.         {
  29.             if(root->right==NULL)    //root的右孩子为空,则创建一个结点作为root的右孩子
  30.             {
  31.                 BSTNode *p=(BSTNode *)malloc(sizeof(BSTNode));
  32.                 p->key=key;
  33.                 p->left=NULL;
  34.                 p->right=NULL;
  35.                 root->right=p;
  36.             }
  37.             else
  38.                 insert(root->right,key);   //递归插入到右子树中
  39.         }
  40.     }
  41. }
 楼主| programmable 发表于 2019-9-14 18:28 | 显示全部楼层
非递归实现:

  1. void insert(BSTNode *&root,ElemType key)   //非递归实现
  2. {
  3.     if(root==NULL)
  4.     {
  5.         root=(BSTNode *)malloc(sizeof(BSTNode));
  6.         root->key=key;
  7.         root->left=NULL;
  8.         root->right=NULL;
  9.         return;
  10.     }
  11.     BSTNode *p1,*p2;
  12.     int flag;
  13.     p1=root;
  14.     while(p1!=NULL)
  15.     {
  16.         p2=p1;
  17.         if(key==p1->key)
  18.             return;
  19.         else if(key<p1->key)
  20.         {
  21.             p1=p1->left;
  22.             flag=0;
  23.         }
  24.         else
  25.         {
  26.             p1=p1->right;
  27.             flag=1;
  28.         }
  29.     }
  30.     BSTNode *p=(BSTNode *)malloc(sizeof(BSTNode));
  31.     p->key=key;
  32.     p->left=NULL;
  33.     p->right=NULL;
  34.     if(flag==0)
  35.         p2->left=p;
  36.     else
  37.         p2->right=p;   
  38. }
 楼主| programmable 发表于 2019-9-14 18:29 | 显示全部楼层
3.二叉排序树的查找

  最坏情况的查找是二叉排序树行成的是一个高度为n的线性树,其平均查找长度跟顺序查找的相同,为n+1/2;

  最好情况是与二分判定树形态相同,其平均查找长度和二分查找相同为logn;

  1. BSTNode* search(BSTNode *root,ElemType key)
  2. {
  3.     if(root==NULL||root->key==key)
  4.         return root;
  5.     else if(key<root->key)
  6.         search(root->left,key);
  7.     else
  8.         search(root->right,key);
  9.   }
  10. BSTNode* search(BSTNode *root,ElemType key)
  11. {
  12.     if(root==NULL||root->key==key)
  13.         return root;
  14.     BSTNode *p=root;
  15.     while(p!=NULL&&key!=p->key)
  16.     {
  17.         if(key<p->key)
  18.             p=p->left;
  19.         else
  20.             p=p->right;
  21.     }
  22.     return p;
  23. }
 楼主| programmable 发表于 2019-9-14 18:29 | 显示全部楼层
关于二叉排序树的运用可以看一下POJ2418

http://poj.org/problem?id=2418

这道题目有2种解法,一种是采用二叉排序树去实现,一种是直接采用STL模板实现,下面只给出STL的实现。

  1. #include<iostream>
  2. #include<string>
  3. #include<map>
  4. #include<algorithm>
  5. using namespace std;

  6. int main(void)
  7. {
  8.     int i;
  9.     int n=0;
  10.     map<string,int> tree;
  11.     map<string,int>::iterator it;
  12.     char str[31];
  13.     while(gets(str))
  14.     {
  15.         string name;
  16.         for(i=0;str[i]!='\0';i++)
  17.         {
  18.             name+=str[i];
  19.         }
  20.         tree[name]++;      //map<string,int>若没有赋初值,则value值默认为0
  21.         n++;
  22.     }
  23.     for(it=tree.begin();it!=tree.end();it++)
  24.     {
  25.         cout<<it->first;
  26.         printf(" %.4lf\n",100*(double)(it->second)/n);
  27.     }
  28.     return 0;
  29. }
 楼主| programmable 发表于 2019-9-14 18:29 | 显示全部楼层
作者:Matrix海子
    
出处:http://www.cnblogs.com/dolphin0520/
    
本博客中未标明转载的**归作者Matrix海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在**页面明显位置给出原文连接,否则保留追究法律责任的权利。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

394

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部