• 二叉查找树 详解


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

    二叉查找树的定义是:

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

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

    主要功能有:

    插入,查找和删除。

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

    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 } 

    查找自己完成。

  • 相关阅读:
    【SpringBoot/CLI】如何创建一个SpringBoot控制台程序
    VMwareworkstation_full_12.1.1.6932 卸载方法
    【Idea】如何更改Idea编辑器字体
    使用idea从git取得Web项目后,启动时出现异常:java.lang.ClassNotFoundException: javax.servlet.http.HttpServletRequest
    【Elasticsearch】如何给ES设置必须以用户名密码访问
    CLR基本原理和如何运用于GOCW
    修改VNC分辨率大小
    判断一个点是否在RotatedRect中
    在C#中使用OpenCV(使用OpenCVSharp)
    求解向量和轮廓的交点
  • 原文地址:https://www.cnblogs.com/1-1-1-1/p/5272355.html
Copyright © 2020-2023  润新知