博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二叉搜索树 (BST) 的创建以及遍历
阅读量:4557 次
发布时间:2019-06-08

本文共 4543 字,大约阅读时间需要 15 分钟。

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

1、BST 的总体结构:

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

其中节点的类如下图:

BST 类代码如下:

1     public class BST
where Tkey : IComparable 2 { 3 private Node root; 4 5 public class Node 6 { 7 private Tkey key; 8 private Tval val; 9 private int n;10 11 public Node(Tkey key, Tval val, int n)12 {13 this.key = key;14 this.val = val;15 }16 public Tkey Key { get => key; }17 public Tval Val { get => val; set => val = value; }18 public Node left { set; get; }19 public Node right { set; get; }20 public int N { set => n = value; get => n; }21 }22 23 public int Size() 24 public void Insert(Tkey, Tval)25 public void Delete(Node x)26 public void InorderTraversal()27 }

 

 

2、插入新节点

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

1 public void Insert(Tkey key, Tval val) 2 { 3     // 创建私有方法,便于传入参数 root 4     root = Insert(root, key, val); 5 } 6  7 private Node Insert(Node x, Tkey key, Tval val) 8 { 9     // 若节点为空(无根节点),则创建新的节点10     if (x == null)11     {12         return new Node(key, val, 1);13     }14 15     // 比较键的大小,小于返回 -1 , 大于返回 1, 等于返回 016     int t = key.CompareTo(x.Key);17 18     if (t > 0) { x.right = Insert(x.right, key, val); }19     else if (t < 0) { x.left = Insert(x.left, key, val); }20     else { x.Val = val; }21 22     x.N = Size(x.left) + Size(x.right) + 1;23 24     return x;25 }

  

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

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

1     public int Size(Node x)2     {3         if (x == null) { return 0; }4         return Size(x.left) + Size(x.right) + 1;5     }

 

 

4、遍历

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

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

中序遍历递归:

1     public void InorderTraversal_recursive(Node x)2     {3         if (x == null) { return; }4 5         InorderTraversal(x.left);6         Console.Write(x.Key + "   ");7         InorderTraversal(x.right);8     }

中序遍历非递归:

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

 

层序遍历:

1     // 利用队列先进先出的特性, 层层输出 2     public void LevelTraversal() 3     { 4         Queue
nodeQueue = new Queue
(); 5 if (root != null) { nodeQueue.Enqueue(root); } 6 7 while (nodeQueue.Count() != 0) 8 { 9 Node currentNode = nodeQueue.Dequeue();10 Console.Write(currentNode.Key + " ");11 // 将去除节点的子节点添加到队列的尾部12 if (currentNode.left != null) { nodeQueue.Enqueue(currentNode.left); }13 if (currentNode.right != null) { nodeQueue.Enqueue(currentNode.right); }14 }15 }

 

5. 证明二叉树为搜索树

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

1     public bool isBST() 2     { 3         Stack
nodeStack = new Stack
(); 4 Node currentNode = root; 5 Node preNode = null; 6 7 8 if (nodeStack.Count() != 0 || currentNode != null) 9 {10 while (currentNode != null)11 {12 nodeStack.Push(currentNode);13 currentNode = currentNode.left;14 }15 16 if (nodeStack.Count() != 0)17 {18 currentNode = nodeStack.Pop();19 // 此处需要判断 preNode 等于空的情况(当进行首个节点判断时,preNOde 为空, 跳过判断) 20 if (preNode != null && currentNode.Key.CompareTo(preNode.Key) <= 0) { return false; }21 22 preNode = currentNode;23 currentNode = currentNode.right;24 }25 }26 return true;27 }

 

转载于:https://www.cnblogs.com/yaolin1228/p/7820515.html

你可能感兴趣的文章
Java中一些常用的类,包,接口
查看>>
下载特定区域内街景照片数据 | Download Street View Photos within Selected Region
查看>>
StarUML 破解方法
查看>>
C语言结构体
查看>>
[转]Tribon船体生产设计应用
查看>>
easy ui datagrid 让某行复选框不能选中
查看>>
第六周作业
查看>>
关于adb端口被占用的解决办法
查看>>
php 部分内置函数的使用
查看>>
字符串处理技巧
查看>>
归档及压缩命令
查看>>
Mybatis步骤
查看>>
WPF自定义控件之扩展原生控件
查看>>
《区块链100问》笔记整理——42~49问
查看>>
使用Jquery+EasyUI 进行框架项目开发案例讲解之二---用户管理源码分享
查看>>
深入理解计算机系统(1.4)---并发与并行、浅谈抽象
查看>>
函数依赖的公理化系统
查看>>
rabbitmq学习(四):利用rabbitmq实现远程rpc调用
查看>>
侯捷C++学习(二)
查看>>
EasyPlayer RTSP Android安卓播放器修复播放画面卡在第一帧bug
查看>>