二叉搜索树 (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 ...
随机推荐
- spring框架总结(03)重点介绍(Spring框架的第二种核心掌握)
1.Spring的AOP编程 什么是AOP? ----- 在软件行业AOP为Aspect Oriented Programming 也就是面向切面编程,使用AOP编程的好处就是:在不修改源代码的情 ...
- 在CentOS7上通过RPM安装实现LAMP+phpMyAdmin过程全记录
在CentOS7上通过RPM安装实现LAMP+phpMyAdmin过程全记录 时间:2017年9月20日 一.软件环境: IP:192.168.1.71 Hostname:centos73-2.sur ...
- php中如何给类规范的注释
@access 使用范围:class,function,var,define,module 该标记用于指明关键字的存取权限:private.public或proteced @author 指明作者 @ ...
- zoj 1539 Lot 简单DP 记忆化
Lot Time Limit: 2 Seconds Memory Limit: 65536 KB Out of N soldiers, standing in one line, it is ...
- Jmeter脚本录制方法(二)——手工编写脚本(jmeter与fiddler结合使用)
jmeter脚本录制方法可以分三种,前几天写的一篇文章中,已介绍了前两种,今天来说下第三种,手工编写脚本,建议使用这一种方法,虽然写的过程有点繁琐,但调试脚本比前两者方式都要便捷. 首先来看下三种方式 ...
- TensorFlow问题:The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations.
1. 问题描述 The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available o ...
- 张高兴的 Xamarin.Android 学习笔记:(四)常用控件
示例地址 GitHub : https://github.com/ZhangGaoxing/xamarin-android-demo/tree/master/ControlsDemo
- Spring装配Bean之Java代码装配bean
尽管通过组件扫描和自动装配实现Spring的自动化配置很方便也推荐,但是有时候自动配置的方式实现不了,就需要明确显示的配置Spring.比如说,想要将第三方库中的组件装配到自己的应用中,这样的情况下, ...
- Django(一)
Django 一.什么是web框架 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演 ...
- 100. Same Tree(leetcode)
Given two binary trees, write a function to check if they are equal or not. Two binary trees are con ...