二叉搜索树 (BST) 的创建以及遍历
二叉搜索树(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) 的创建以及遍历的更多相关文章
- C++版 - 剑指offer 面试题24:二叉搜索树BST的后序遍历序列(的判断) 题解
剑指offer 面试题24:二叉搜索树的后序遍历序列(的判断) 题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则返回true.否则返回false.假设输入的数组的任意两个 ...
- 萌新笔记之二叉搜索树(BST)
前言,以前搞过线段树,二叉树觉得也就那样= =.然后数据结构的课也没怎么听过,然后下周期中考... 本来以为今天英语考完可以好好搞ACM了,然后这个数据结构期中考感觉会丢人,还是好好学习一波. 二叉搜 ...
- 给定一个二叉搜索树(BST),找到树中第 K 小的节点
问题:给定一个二叉搜索树(BST),找到树中第 K 小的节点. 出题人:阿里巴巴出题专家:文景/阿里云 CDN 资深技术专家. 考察点: 1. 基础数据结构的理解和编码能力 2. 递归使用 参考答案 ...
- PAT L2-004. 这是二叉搜索树吗?【前序遍历转化为后序遍历】
一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点, 其左子树中所有结点的键值小于该结点的键值: 其右子树中所有结点的键值大于等于该结点的键值: 其左右子树都是二叉搜索树. 所谓二叉搜索 ...
- 二叉搜索树(BST)
(第一段日常扯蛋,大家不要看)这几天就要回家了,osgearth暂时也不想弄了,毕竟不是几天就能弄出来的,所以打算过完年回来再弄.这几天闲着也是闲着,就掏出了之前买的算法导论看了看,把二叉搜索树实现了 ...
- 数据结构☞二叉搜索树BST
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它可以是一棵空树,也可以是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它 ...
- 看动画学算法之:二叉搜索树BST
目录 简介 BST的基本性质 BST的构建 BST的搜索 BST的插入 BST的删除 简介 树是类似于链表的数据结构,和链表的线性结构不同的是,树是具有层次结构的非线性的数据结构. 树是由很多个节点组 ...
- 在二叉搜索树(BST)中查找第K个大的结点之非递归实现
一个被广泛使用的面试题: 给定一个二叉搜索树,请找出其中的第K个大的结点. PS:我第一次在面试的时候被问到这个问题而且让我直接在白纸上写的时候,直接蒙圈了,因为没有刷题准备,所以就会有伤害.(面完的 ...
- [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 ...
随机推荐
- [C语言]贪吃蛇_结构数组实现
一.设计思路 蛇身本质上就是个结构数组,数组里存储了坐标x.y的值,再通过一个循环把它打印出来,蛇的移动则是不断地刷新重新打印.所以撞墙.咬到自己只是数组x.y值的简单比较. 二.用上的知识点 结构数 ...
- java数据库编程之初始Mysql
2.3:命令行连接mySql 2.3.1:检查是否启动服务 步骤:计算机-----管理------服务和应用程序-------服务---搜索mysql右键启动服务 2.3.2:命令行方式连接数据库 步 ...
- 5分钟教你玩转 sklearn 机器学习(上)
假期结束,你的状态有没有回归?那么,放空脑袋后,先来学习学习,欢迎大家继续关注腾讯云技术社区. 作者:赵成龙 这是一篇很难写的文章,因为我希望这篇文章能对大家有所帮助.我不会给大家介绍机器学习,数据挖 ...
- Java历程-初学篇 Day07 循环结构2 for循环
一,格式 for(赋值语句//为循环变量赋初值;条件语句//循环结构的循环条件;赋值语句//迭代,修改循环变量的值){ //循环体; } 二,简单举例 for(int i=1;i<=10;i++ ...
- MVC中Controller控制器相关技术
第6章Controller相关技术 Controller(控制器)在ASP.NET MVC中负责控制所有客户端与服务器端的交互,并 且负责协调Model与View之间的数椐传递,是ASP.NET MV ...
- dotweb框架之旅 [二] - 常用对象-App(dotweb)
dotweb属于一个Web框架,希望通过框架行为,帮助开发人员快速构建Web应用,提升开发效率,减少不必要的代码臃肿. dotweb包含以下几个常用对象: App(dotweb) App容器,为Web ...
- Charle抓包与wireshark使用
今天就来看一下Mac上如何进行抓包,之前有一篇文章介绍了使用Fidder进行抓包 http://blog.csdn.net/jiangwei0910410003/article/details/198 ...
- ReactiveCocoa基础和一些常见类介绍
一 导入ReactiveCocoa框架 通常都会使用CocoaPods(用于管理第三方框架的插件)帮助我们导入 podfile如果只描述pod 'ReactiveCocoa', '~> 4.0. ...
- Git 工作流的正确打开方式
前言 一直在使用git做版本控制,也一直工作很顺利,直到和别人发生冲突的时候.这才注意到git 工作流并不是那么简单.比如,之前遇到的清理历史.百度到的资料很多,重复性也很多,但实践性操作很少,我很难 ...
- .net 面试题
1.列举ASP.NET页面之间传值的几种方式. 答:使用QueryString,如.../id=1;response.Redirect() 使用Session 使用Server.Transfer 使用 ...