二叉查找树 详解

Posted 社会主义市场经济

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉查找树 详解相关的知识,希望对你有一定的参考价值。

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

二叉查找树的定义是:

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

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

技术分享

主要功能有:

插入,查找和删除。

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

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\n";
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 } 

查找自己完成。

以上是关于二叉查找树 详解的主要内容,如果未能解决你的问题,请参考以下文章

二叉查找树 详解

二叉查找树详解

二叉查找树详解

详解二叉查找树(BST)

二叉查找树简单实现

数据结构与算法查找(Search)详解