1.先序遍历



2.中序遍历



3.后序遍历



4.递归调用栈详解:



详细见: https://zhuanlan.zhihu.com/p/24291978

5.删除节点操作分析:



5.代码封装

 //封装二叉搜索树
function BinarySearchTree() {
//封装节点内部类
function Node(key) {
this.key = key
this.left = null
this.right = null
}
//属性
this.root = null
//方法
// 1. insert方法
BinarySearchTree.prototype.insert = function(key) {
var newNode = new Node(key)
if (this.root == null) {
this.root = newNode
} else {
this.insertNode(this.root, newNode)
}
}
//封装一个递归方法
BinarySearchTree.prototype.insertNode = function(node, newNode) {
if (newNode.key > node.key) {
if (node.left == null) {
node.left = newNode
} else {
this.insertNode(node.left, newNode)
}
} else {
if (node.right == null) {
node.right = newNode
} else {
this.insertNode(node.right, newNode)
}
}
} // 遍历方式
// 1. 先序遍历
BinarySearchTree.prototype.preOrderTranversal = function(handle) { //handle 为传入的处理key的函数
this.preOrderTranversalNode(this.ropot, handle)
}
//定义一个遍历节点的方法
BinarySearchTree.prototype.preOrderTranversalNode = function(node, handle) {
if (node !== null) {
handle(node.key)
// 先序遍历左节点
this.preOrderTranversalNode(node.left, handle)
//先序遍历右节点
this.preOrderTranversalNode(node.right, handle)
}
}
// 2.中序遍历
BinarySearchTree.prototype.midOrderTranversal = function(handle) { //handle 为传入的处理key的函数
this.midOrderTranversalNode(this.ropot, handle)
}
//定义一个遍历节点的方法
BinarySearchTree.prototype.midOrderTranversalNode = function(node, handle) {
if (node !== null) {
// 先序遍历左节点
this.midOrderTranversalNode(node.left, handle)
handle(node.key) //先序遍历右节点
this.midOrderTranversalNode(node.right, handle)
}
}
// 3.后序遍历
BinarySearchTree.prototype.postOrderTranversal = function(handle) { //handle 为传入的处理key的函数
this.postOrderTranversalNode(this.ropot, handle)
}
//定义一个遍历节点的方法
BinarySearchTree.prototype.postOrderTranversalNode = function(node, handle) {
if (node !== null) {
// 先序遍历左节点
this.postOrderTranversalNode(node.left, handle) //先序遍历右节点
this.postOrderTranversalNode(node.right, handle)
handle(node.key) }
}
// 寻找最值
// 最大值
BinarySearchTree.prototype.max = function() {
var node = this.root
while (node.right !== null) {
node = node.right
}
return node.key
}
// 最小值
BinarySearchTree.prototype.min = function() {
var node = this.root
while (node.left !== null) {
node = node.left
}
return node.key
} //搜索特定key BinarySearchTree.prototype.search = function(key) {
// 1.通过循环实现
var node =this.root
while (node !== null) {
if (node.key < key ) {
node = node.right
} else if(node.key > key) {
node = node.left
} else {
return true
}
return false
} // 2.通过递归实现
this.searchNode(this.root)
}
//递归函数封装
BinarySearchTree.prototype.searchNode = function(node, key) {
if (node == null) {
return false
}
if (node.key < key) {
this.searchNode(node.left)
} else if(node.key > key) {
this.searchNode(node.right)
} else {
return true
}
}
//删除操作
BinarySearchTree.prototype.remove = function(key) {
var current = this.root
var parent = null
var isLeftChild = true
//寻找key对应的节点
while (current.key != key) {
parent = current
if (current.key < key) {
isLeftChild = true
current = current.right
} else {
isLeftChild = false
current = current.left
}
if (current == null) {
return false
}
}
//找到了key对应的节点
// 删除的节点是叶子节点
if(current.left == null && current.right == null) {
//是根节点
if(current == this.root) {this.root = null}
//
else { isLeftChild ? parent.left = null: parent.right =null}
}
//节点有一个子节点
else if (current.left == null || current.right == null) {
//当前删除的节点是父节点的左节点
if (current == this.root) { this.root = current.left || current.right}
else if (isLeftChild) {
parent.left = current.left || current.right
}
//当前删除的节点是父节点的右节点
else{
parent.right = current.right || current.left
}
}
//节点有两个子节点
else {
var successor = this.getSuccessor(current)
if (successor == this.root) {
this.root = successor
} else {
if (isLeftChild) {
parent.left = successor
} else {
parent.right = successor
}
}
successor.left = current.left
}
}
//寻找后继的方法
BinarySearchTree.prototype.getSuccessor = function(delNode) {
var successor = delNode //后继节点的父节点
var current = delNode.right //后继节点的子节点
var successorParent = delNode //后继节点
while (current != null) {
successorParent = successor
successor = current
current = current.left
}
if (successor != delNode.right) { //当后继节点的不是删除节点的右节点时
successorParent.left = successor.right //把后记节点的右节点让后继节点的父节点的left指向它
successor.right = delNode.right //、把后继节点的右节点接上删除节点的右节点
}
return successor
}
}

删除操作总结:

(js描述的)数据结构[树结构1.2](12)的更多相关文章

  1. (js描述的)数据结构[树结构1.1](11)

    1.树结构: 我们不能说树结构比其他结构都要好,因为每种数据结构都有自己特定的应用场景. 但是树确实也综合了上面的数据结构的优点(当然有点不足于盖过其他的数据结构,比如效率一般情况下没有哈希表高) 并 ...

  2. (js描述的)数据结构[树结构之红黑树](13)

    1.二叉送搜索树的缺点: 2.红黑树难度: 3.红黑树五大规则: 4.红黑树五大规则的作用: 5.红黑树二大变换: 1)变色 2)旋转 6.红黑树的插入五种变换情况: 先声明--------插入的数据 ...

  3. (js描述的)数据结构[双向链表](5)

    (js描述的)数据结构[双向链表](5) 一.单向链表的缺点 1.只能按顺序查找,即从上一个到下一个,不能反过来. 二.双向链表的优点 1.可以双向查找 三.双向链表的缺点 1.结构较单向链表复杂. ...

  4. (js描述的)数据结构[哈希表1.1](8)

    (js描述的)数据结构[哈希表1.1](8) 一.数组的缺点 1.数组进行插入操作时,效率比较低. 2.数组基于索引去查找的操作效率非常高,基于内容去查找效率很低. 3.数组进行删除操作,效率也不高. ...

  5. (js描述的)数据结构[字典](7)

    (js描述的)数据结构[字典](7) 一.字典的特点 1.字典的主要特点是一一对应关系. 2.使用字典,剋通过key取出对应的value值. 3.字典中的key是不允许重复的,而value值是可以重复 ...

  6. (js描述的)数据结构[集合结构](6)

    (js描述的)数据结构[集合结构](6) 一.集合结构特点 1.集合中的元素不能重复. 2.集合是无序的. 二.集合的代码实现 function Set() { this.items = {} //1 ...

  7. (js描述的)数据结构[链表](4)

    (js描述的)数据结构 [链表](4) 一.基本结构 二.想比于数组,链表的一些优点 1.内存空间不是必须连续的,可以充分利用计算机的内存,事项灵活的内存动态管理. 2.链表不必再创建时就确定大小,并 ...

  8. (js描述的)数据结构[队列结构,优先级队列](3)

    (js描述的)数据结构[队列结构](3) 一.队列结构的特点: 1.基于数组来实现,的一种受限的线性结构. 2.只允许在表头进行删除操作,在表尾进行插入操作. 3.先进先出(FIFO) 二.队列的一些 ...

  9. (js描述的)数据结构[栈结构](2)

    (js描述的)数据结构[栈结构](2) 一.什么是栈结构 1.一种受限制的线性结构,这种结构可以基于数组来实现. 2.可以抽象成一个容器,上面的是栈顶,底下的是栈底.所以仅允许对栈顶进行操作, 二.栈 ...

随机推荐

  1. 工作5年了还说不清bean生命周期?大厂offer怎么可能给你!

    第一,这绝对是一个面试高频题. 比第一还重要的第二,这绝对是一个让人爱恨交加的面试题.为什么这么说?我觉得可以从三个方面来说: 先说会不会.看过源码的人,这个不难:没看过源码的人,无论是学.硬背.还是 ...

  2. ajax3

    json json:JavaScript对象表示方法(JavaScript object notation) json:是存储和交换文本信息的语法,类似与xml.他使用键值对的方式来组织,易于人们阅读 ...

  3. 小白的docker极简入门(二)、5分钟教你玩转docker安装

    0-前言 上一篇中,我们已经安装后Linux了,我们需要在Linux下安装docker,然后才能在docker中安装和部署各种应用 同样,5分钟教你完成docker正确安装和使用, 不是纸上谈兵,不是 ...

  4. AVR单片机教程——走向高层

    本文隶属于AVR单片机教程系列.   在系列教程的最后一篇中,我将向你推荐3个可以深造的方向:RTOS.C++.事件驱动.掌握这些技术可以帮助你更快.更好地开发更大的项目. 本文涉及到许多概念性的内容 ...

  5. 面试官再问我如何保证 RocketMQ 不丢失消息,这回我笑了!

    最近看了 @JavaGuide 发布的一篇『面试官问我如何保证Kafka不丢失消息?我哭了!』,这篇文章承接这个主题,来聊聊如何保证 RocketMQ 不丢失消息. 0x00. 消息的发送流程 一条消 ...

  6. 几十万学费总结出来的Ddos攻击防护经验!

    本人从事网络安全行业十余年年.有十年被骗经验.被骗了很多回(都说能防300G,500G,买完就防不住了),本文当然重点给大家说明,ddos攻击是什么,中小企业如何防护,用到成本等. 言归正传 首先我们 ...

  7. 深入理解JAVA字符串常量池

    初学JAVA时,在学习如何比较两个字符串是否相等,大量资料告诉我,不能用等于号( = )去比较,需要使用equals方法,理由是String是一个对象,等号此时比较的是两个字符串在java内存堆中的地 ...

  8. Effective python(五):内置模块

    1,考虑使用contextlib和with语句改写可复用的try/finally代码 with lock:print('lock is held')相当于try:print('lock is held ...

  9. 图-连通分量-DFS-并查集-695. 岛屿的最大面积

    2020-03-15 16:41:45 问题描述: 给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二 ...

  10. vscode快速生成html模板(vscode快捷键"!"生成html模板)

    问题: 在vscode中新建test.html, 内容是空白的,输入"!",然后按tap键 ,没有生成常见的html模板,也就是如下: 输入! html html:5 DOCTYP ...