二叉搜索树(Binary Search Tree) : 属于二叉树,其中每个节点都含有一个可以比较的键(如需要可以在键上关联值), 且每个节点的键都大于其左子树中的任意节点而小于右子树的任意节点的键。

1、BST 的总体结构:

主要的几种变量以及方法如上图所示,主要有插入、排序、删除以及查找等方法。键采用泛型,继承 IComparable, 便于比较。

其中节点的类如下图:

BST 类代码如下:

     public class BST<Tkey, Tval> where Tkey : IComparable
{
private Node root; public class Node
{
private Tkey key;
private Tval val;
private int n; public Node(Tkey key, Tval val, int n)
{
this.key = key;
this.val = val;
}
public Tkey Key { get => key; }
public Tval Val { get => val; set => val = value; }
public Node left { set; get; }
public Node right { set; get; }
public int N { set => n = value; get => n; }
} public int Size()
public void Insert(Tkey, Tval)
public void Delete(Node x)
public void InorderTraversal()
}

2、插入新节点

根据键大于左节点, 小于右节点的定义,可用如下代码实现新节点的插入:

 public void Insert(Tkey key, Tval val)
{
// 创建私有方法,便于传入参数 root
root = Insert(root, key, val);
} private Node Insert(Node x, Tkey key, Tval val)
{
// 若节点为空(无根节点),则创建新的节点
if (x == null)
{
return new Node(key, val, );
} // 比较键的大小,小于返回 -1 , 大于返回 1, 等于返回 0
int t = key.CompareTo(x.Key); if (t > ) { x.right = Insert(x.right, key, val); }
else if (t < ) { x.left = Insert(x.left, key, val); }
else { x.Val = val; } x.N = Size(x.left) + Size(x.right) + ; return x;
}

3、计算以该节点为根的节点总节点数

采用递归的方法,从根节点到循环到叶子节点

     public int Size(Node x)
{
if (x == null) { return ; }
return Size(x.left) + Size(x.right) + ;
}

4、遍历

遍历分为广度遍历与深度遍历,如下图所示:

深度优先遍历的几种方式原理相似, 只是输出的节点键的位置不同而已。

中序遍历递归:

     public void InorderTraversal_recursive(Node x)
{
if (x == null) { return; } InorderTraversal(x.left);
Console.Write(x.Key + " ");
InorderTraversal(x.right);
}

中序遍历非递归:

     public void  InorderTraversal_stack()   // 利用堆栈先进后出的特性, 先将全部左节点压入,然后输出左节点,每输出一个左节点后切换到右节点, 继续输出
{
Stack<Node> nodeStack = new Stack<Node>();
Node currentNode = root; while (nodeStack != null || currentNode != null) // 此处判断 curretNode 非空,是因为首次循环 nodeStack 为空, 避免了在循环外添加根节点。
{
while (currentNode != null) // 将全部左节点压入堆栈
{
nodeStack.Push(currentNode);
currentNode = currentNode.left;
}
if (nodeStack.count != 0)
{
currentNode = nodeStack.Pop();
Console.Write(currentNode.key + " ");
currentNode = currentNode.right; // 切换到右节点
}
}
}

层序遍历:

     // 利用队列先进先出的特性, 层层输出
public void LevelTraversal()
{
Queue<Node> nodeQueue = new Queue<Node>();
if (root != null) { nodeQueue.Enqueue(root); } while (nodeQueue.Count() != )
{
Node currentNode = nodeQueue.Dequeue();
Console.Write(currentNode.Key + " ");
// 将去除节点的子节点添加到队列的尾部
if (currentNode.left != null) { nodeQueue.Enqueue(currentNode.left); }
if (currentNode.right != null) { nodeQueue.Enqueue(currentNode.right); }
}
}

5. 证明二叉树为搜索树

根据定义,搜索树是二叉树的基础上添加的一个条件: 节点左子树全部节点小于节点, 节点右子树大于节点。中序遍历,全部节点按序遍历,由此我们只需要证明后一个节点大于前一个节点。

     public bool isBST()
{
Stack<Node> nodeStack = new Stack<Node>();
Node currentNode = root;
Node preNode = null; if (nodeStack.Count() != || currentNode != null)
{
while (currentNode != null)
{
nodeStack.Push(currentNode);
currentNode = currentNode.left;
} if (nodeStack.Count() != )
{
currentNode = nodeStack.Pop();
// 此处需要判断 preNode 等于空的情况(当进行首个节点判断时,preNOde 为空, 跳过判断)
if (preNode != null && currentNode.Key.CompareTo(preNode.Key) <= ) { return false; } preNode = currentNode;
currentNode = currentNode.right;
}
}
return true;
}

二叉搜索树 (BST) 的创建以及遍历的更多相关文章

  1. C++版 - 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解

    剑指offer 面试题24:二叉搜索树的后序遍历序列(的判断) 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true.否则返回false.假设输入的数组的任意两个 ...

  2. 萌新笔记之二叉搜索树(BST)

    前言,以前搞过线段树,二叉树觉得也就那样= =.然后数据结构的课也没怎么听过,然后下周期中考... 本来以为今天英语考完可以好好搞ACM了,然后这个数据结构期中考感觉会丢人,还是好好学习一波. 二叉搜 ...

  3. 给定一个二叉搜索树(BST),找到树中第 K 小的节点

    问题:给定一个二叉搜索树(BST),找到树中第 K 小的节点. 出题人:阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家. 考察点: 1. 基础数据结构的理解和编码能力 2.  递归使用 参考答案 ...

  4. PAT L2-004. 这是二叉搜索树吗?【前序遍历转化为后序遍历】

    一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点, 其左子树中所有结点的键值小于该结点的键值: 其右子树中所有结点的键值大于等于该结点的键值: 其左右子树都是二叉搜索树. 所谓二叉搜索 ...

  5. 二叉搜索树(BST)

    (第一段日常扯蛋,大家不要看)这几天就要回家了,osgearth暂时也不想弄了,毕竟不是几天就能弄出来的,所以打算过完年回来再弄.这几天闲着也是闲着,就掏出了之前买的算法导论看了看,把二叉搜索树实现了 ...

  6. 数据结构☞二叉搜索树BST

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它可以是一棵空树,也可以是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它 ...

  7. 看动画学算法之:二叉搜索树BST

    目录 简介 BST的基本性质 BST的构建 BST的搜索 BST的插入 BST的删除 简介 树是类似于链表的数据结构,和链表的线性结构不同的是,树是具有层次结构的非线性的数据结构. 树是由很多个节点组 ...

  8. 在二叉搜索树(BST)中查找第K个大的结点之非递归实现

    一个被广泛使用的面试题: 给定一个二叉搜索树,请找出其中的第K个大的结点. PS:我第一次在面试的时候被问到这个问题而且让我直接在白纸上写的时候,直接蒙圈了,因为没有刷题准备,所以就会有伤害.(面完的 ...

  9. [LeetCode] Convert BST to Greater Tree 将二叉搜索树BST转为较大树

    Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original B ...

随机推荐

  1. 初识Hibernate之关联映射(一)

    上篇文章我们对持久化对象进行的学习,了解了它的三种不同的状态并通过它完成对数据库的映射操作.但这都是基于单张表的操作,如果两张或者两张以上的表之间存在某种关联,我们又该如何利用持久化对象进行操作呢?本 ...

  2. 数据的分类-JavaScript数据类型

    JavaScript数据类型 1.数据类型是什么? 我们接触的绝大多数程序语言来说,把数据都进行了分类,包括数字.字符.逻辑真假:int,long,string,boolean....等等:我们都知道 ...

  3. centos crontab(定时任务) 使用

    一.介绍   crontab命令的功能是在一定的时间间隔调度一些命令的执行.当安装完成操作系统之后,默认便会启动此任务调度命令.crond命令每分锺会定期检查是否有要执行的工作,如果有要执行的工作便会 ...

  4. android中跨线程向控件传值的问题

    activity.oncreate(bundle savedinstancestate)中创建一个handler类的实例, 在这个handler实例的handlemessage回调函数中调用更新界面显 ...

  5. js-location应用

    1 location.search ?xxx=sss&yyy=ddd 获取地址中查询的值 /** * 解析url参数 * @example ?id=123456&a=b * @retu ...

  6. Hadoop(四)HDFS集群详解

    前言 前面几篇简单介绍了什么是大数据和Hadoop,也说了怎么搭建最简单的伪分布式和全分布式的hadoop集群.接下来这篇我详细的分享一下HDFS. HDFS前言: 设计思想:(分而治之)将大文件.大 ...

  7. ORALCE PL/SQL学习笔记

    ORALCE  PL/SQL学习笔记 详情见自己电脑的备份数据资料

  8. Java面向对象 其他对象

     Java面向对象  其他对象 知识概要:             (1)可变参数 (2)静态导入 (3)System (4)Runtime (5)Date  Calendar (6)Math 本 ...

  9. Mysql的二进制安装和基础入门操作

    前言:Mysql数据库,知识非常的多,要想学精学通这块知识,估计也要花费和学linux一样的精力和时间.小编也是只会些毛皮,给大家分享一下~ 一.MySQL安装 (1)安装方式: 1 .程序包yum安 ...

  10. 学习总结---BGP协议

    一.可以在自治域内使用BGP作为域内协议吗? 为什么?它和OSPF的关键差异是什么? 1.BGP的全称是边界网关协议,用于自治域间的路由传递,它不像OSPF协议,其重点不在于路由的计算,而在于路由的控 ...