二叉查找树 详解

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

二叉查找树的定义是:

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

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

主要功能有:

插入,查找和删除。

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

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 } 

查找自己完成。

时间: 2024-10-24 01:20:10

二叉查找树 详解的相关文章

二叉查找树详解

二叉查找树性质 1.二叉树 每个树的节点最多有两个子节点的树叫做二叉树. 2.二叉查找树 一颗二叉查找树是按照二叉树的结构来组织的,并且满足一下性质: 一个节点所有左子树上的节点不大于盖节点,所有右子树的节点不小于该节点. 对查找树的操作查询,插入,删除等操作的时间复杂度和树的高度成正比, 因此,构建高效的查找树尤为重要. 查找树的遍历 先序遍历 查找树的遍历可以很简单的采用递归的方法来实现. struct list { struct list *left;//左子树 struct list *

二叉查找树(binary search tree)详解

二叉查找树(Binary Search Tree),也称二叉排序树(binary sorted tree),是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值 任意节点的左.右子树也分别为二叉查找树 没有键值相等的节点(no duplicate nodes) 本文地址:http://www.cnblogs.com/archimedes/p/binary-search-tree

详解二叉查找树(BST)

详解二叉查找树(BST) 本篇随笔简单讲解一下数据结构--二叉查找树(\(Binary\,\,Sort\,\,Tree,BST\)),(后文的"二叉查找树"一词均用\(BST\)代替). BST的概念 首先,\(BST\)是一棵二叉树. 它的定义是,根节点左子树全部严格小于根节点,右子树大于等于根节点,并且,左右子树都是\(BST\). 很好理解,很明朗很简单的定义. 可以看出,这是一个通过递归方式定义的数据结构,所以,它的诸多操作自然要用到递归. BST的功能 我们可以看出来,这个二

二叉树的应用详解 - 数据结构

二叉树的应用详解 - 数据结构 概述: 平衡树——特点:所有结点左右子树深度差≤1 排序树——特点:所有结点“左小右大字典树——由字符串构成的二叉排序树判定树——特点:分支查找树(例如12个球如何只称3次便分出轻重)带权树——特点:路径带权值(例如长度) 最优树——是带权路径长度最短的树,又称 Huffman树,用途之一是通信中的压缩编码. 1. 二叉排序树(二叉查找树 Binary Search Tree): 1.1 二叉排序树: 或是一棵空树:或者是具有如下性质的非空二叉树: (1)若左子树

深入Java基础(四)--哈希表(1)HashMap应用及源码详解

继续深入Java基础系列.今天是研究下哈希表,毕竟我们很多应用层的查找存储框架都是哈希作为它的根数据结构进行封装的嘛. 本系列: (1)深入Java基础(一)--基本数据类型及其包装类 (2)深入Java基础(二)--字符串家族 (3)深入Java基础(三)–集合(1)集合父类以及父接口源码及理解 (4)深入Java基础(三)–集合(2)ArrayList和其继承树源码解析以及其注意事项 文章结构:(1)哈希概述及HashMap应用:(2)HashMap源码分析:(3)再次总结关键点 一.哈希概

查找(二)简单清晰的B树、Trie树详解

查找(二) 散列表 散列表是普通数组概念的推广.由于对普通数组可以直接寻址,使得能在O(1)时间内访问数组中的任意位置.在散列表中,不是直接把关键字作为数组的下标,而是根据关键字计算出相应的下标. 使用散列的查找算法分为两步.第一步是用散列函数将被查找的键转化为数组的一个索引. 我们需要面对两个或多个键都会散列到相同的索引值的情况.因此,第二步就是一个处理碰撞冲突的过程,由两种经典解决碰撞的方法:拉链法和线性探测法. 散列表是算法在时间和空间上作出权衡的经典例子. 如果没有内存限制,我们可以直接

Java集合详解6:TreeMap和红黑树

Java集合详解6:TreeMap和红黑树 初识TreeMap 之前的文章讲解了两种Map,分别是HashMap与LinkedHashMap,它们保证了以O(1)的时间复杂度进行增.删.改.查,从存储角度考虑,这两种数据结构是非常优秀的.另外,LinkedHashMap还额外地保证了Map的遍历顺序可以与put顺序一致,解决了HashMap本身无序的问题. 尽管如此,HashMap与LinkedHashMap还是有自己的局限性----它们不具备统计性能,或者说它们的统计性能时间复杂度并不是很好才

AVL树平衡旋转详解

AVL树平衡旋转详解 概述 AVL树又叫做平衡二叉树.前言部分我也有说到,AVL树的前提是二叉排序树(BST或叫做二叉查找树).由于在生成BST树的过程中可能会出现线型树结构,比如插入的顺序是:1, 2, 3, 4, 5, 6, 7..., n.在BST树中,比较理想的状况是每个子树的左子树和右子树的高度相等,此时搜索的时间复杂度是log(N).可是,一旦这棵树演化成了线型树的时候,这个理想的情况就不存在了,此时搜索的时间复杂度是O(N),在数据量很大的情况下,我们并不愿意看到这样的结果. 现在

Java集合详解6:这次,从头到尾带你解读Java中的红黑树

<Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star.fork哈 文章首发于我的个人博客: www.how2playlife.com 什么是红黑树 首先,什么是红黑树呢? 红黑树是一种"平衡的"二叉查找树,它是一种经典高效的算法,能够保证