二叉搜索树(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. Theano学习-scan循环

    \(1.Scan\) 通用的一般形式,可用于循环 减少和映射(对维数循环)是特殊的 \(scan\) 对输入序列进行 \(scan\) 操作,每一步都能得到一个输出 \(scan\) 能看到定义函数的 ...

  2. linux下快速列出文件列表的方法

    前言 这两天碰到一个很棘手的问题,需要读取出ubuntu系统中某个目录下所有文件,由于服务器中存储的文件实在太多,导致此过程效率十分低下,动辄需要等待一个小时之久,还只是一个目录.于是如何快速获取文件 ...

  3. Log4j按级别输出日志到不同文件配置分析 (转:projava)

    关于LOG4J 按照级别输出日志,并按照级别输出到不同文件中的说法有很多, 网上贴的最多的log4j.properties的设置是这样的 log4j.rootLogger=info,stdout,in ...

  4. The Twelve-Factor App 实践

    The Twelve-Factor App <The Twelve-Factor App>定义了一个优雅的互联网应用在设计过程中,尤其是在设计SAAS服务时,需要遵循的一些基本原则.本文为 ...

  5. ionic构建APP--简单操作实现APP制作

    ionic--基于AngularJS的app框架 1安装ionic .HBuilder创建APP项目,导入ionic的css,js(fonts)文件. .导入ionic.css和ionic.bundl ...

  6. JS 巧用 && 与 ||

    在对于流程控制语句当中,我们最熟悉不过的就是 if (条件){ //代码块 }else{ //代码块 } 对于一个执行不同的代码来说,如果执行的代码很多,可能就有必要使用上面这种方式 但往往我们开发当 ...

  7. C# 判断文件编码

    我们的项目中会包含有很多文件,但是可能我们没有注意到的,我们的文件的编码不一定是utf-8,所以可能在别人电脑运行时出现乱码.最近在做一个项目,这个项目可以把我们的文件夹里的所有文本,判断他们是什么编 ...

  8. JS中replace()用法举例

    语法: string.replace(regexp,replacement) 参数: regexp:声明了要替换的模式的RegExp对象.如果该参数是一个字符串,则将它作为要检索的直接量文本模式,而不 ...

  9. LINUX 笔记-iproute2 命令

    一.IP 地址管理 1.显示 IP 地址 ip addr show [dev eth0] 2.增加删除 IP 地址 ip addr add 192.0.2.1/24 dev eth0 ip addr ...

  10. LeetCode 245. Shortest Word Distance III (最短单词距离之三) $

    This is a follow up of Shortest Word Distance. The only difference is now word1 could be the same as ...