zoukankan      html  css  js  c++  java
  • 二叉查找树 详解

    二叉查找树又称二叉搜索树,是一种效率极高的数据结构。

    二叉查找树的定义是:

    对于一棵二叉查找树上的一个节点,他的左子树上的任何一个值都比它小,右子树上的任何一个值都比它大(不考虑相等的情况)。他的左右子树又是一棵二叉查找树。

    比如下图就是一个二叉查找树:

    主要功能有:

    插入,查找和删除。

    我们还需要定义一个结构体:

    1 struct node{                               //结构体 
    2     int data;                                   //数据 
    3     node *left,*right,*parent;                     //指针 
    4     node() : data(0),left(NULL),right(NULL),parent(NULL){}  //构造函数 
    5 };                           //分号 

    由二叉查找树的性质可以显而易见地知道,Insert和find的效率约等于二叉树的深度,效率在O(log2n)~O(n)之间。而delete_node的效率为O(1)。

    本文只实现上面两个,第三个自己写。

    由二叉查找树的性质可以显而易见地知道,Insert只需要向下摸索就能找到他应该存放的位置,下面是代码:

     1 int Insert(int x,node *now){ //建树 
     2     if(now->data==0){        //判断树是否为空 
     3         now->data=x;         //为空就赋值 
     4         return 0;            //返回 
     5     }else{                  //否则 
     6         if(now->data>x){     //找自己应该放在哪个位置,如果x小于当前节点的值 
     7             if(now->left!=end){         //如果左子树不是空 
     8                 Insert(x,now->left);  //向下递归 
     9             }else{                      //否则 
    10                 node *p=new node;       //定义node型指针并给它申请新空间 
    11                 p->data=x;              //将x放进去 
    12                 p->parent=now;          //将它和它父母连上去 
    13                 p->left=end;            //指向结束,代表空 
    14                 p->right=end;           //指向结束 
    15                 now->left=p;            //将父母和自己连起来 
    16                 return 0;                //返回 
    17             }                          //花括号 
    18         }else{                        //否则      
    19             if(now->right!=end){      //如果右子树不是空   
    20                 Insert(x,now->right);  //向下递归 
    21             }else{                      //否则 
    22                 node *p=new node;       //定义node型指针并给它申请新空间 
    23                 p->data=x;              //将x放进去 
    24                 p->parent=now;          //将它和它父母连上去 
    25                 p->left=end;           //指向结束,代表空 
    26                 p->right=end;            //指向结束,代表空 
    27                 now->right=p;           //将父母和自己连起来 
    28                 return 0;                //返回 
    29             }                          //花括号 
    30         }                             //花括号 
    31     }                                 //花括号 
    32 }                                     //花括号 

    删除就比较麻烦了,要分类讨论

    如果删除的节点没有孩子的话,就直接删掉就是了。

    如果有一个孩子,那就将父亲的孩子变为自己的孩子。

    如果有两个,就找最接近自己的一个(可以通过中序遍历找,也可以用特殊方法)

    下面是代码:

     1 int delete_node(int x){              //删除部分不写注释 
     2     node *now=root;
     3     while(now->data!=x){
     4         if(now->data>x)
     5             now=now->left;
     6         else
     7             now=now->right;
     8     }
     9     if(now->data!=x){           
    10         cout<<"no
    ";
    11         return 0;
    12     }else{
    13         if(now->left==end){
    14             node *p=now->parent;
    15             if(p->left==now)
    16                 p->left=now->right;
    17             else
    18                 p->right=now->right;
    19             delete now;
    20             return 1;
    21         }else{
    22             if(now->right==end){
    23                 node *p=now->parent;
    24                 if(p->left==now)
    25                     p->left=now->left;
    26                 else
    27                     p->right=now->left;
    28                 delete now;
    29                 return 1;
    30             }else{
    31                 node *p=now->left;
    32                 while(p->right!=end)
    33                     p=p->right;
    34                 now->data=p->data;
    35                 if(p->parent!=now)
    36                     p->parent->right=p->left;
    37                 else
    38                     p->parent->left=end;
    39                 delete p;
    40                 return 1;
    41             }
    42         }
    43     }
    44 } 

    查找自己完成。

  • 相关阅读:
    算法训练 P1103
    算法训练 表达式计算
    算法训练 表达式计算
    基础练习 时间转换
    基础练习 字符串对比
    Codeforces 527D Clique Problem
    Codeforces 527C Glass Carving
    Codeforces 527B Error Correct System
    Codeforces 527A Glass Carving
    Topcoder SRM 655 DIV1 250 CountryGroupHard
  • 原文地址:https://www.cnblogs.com/1-1-1-1/p/5272355.html
Copyright © 2011-2022 走看看