vlambda博客
学习文章列表

js数据结构与算法(二叉树、二叉查找树)

树是一种数据结构,该章节讨论二叉树(二叉树的每个节点的子节点不允许超过两个),二叉树中有又分为完全二叉树和不完全二叉树.....

不在本章节赘述相关概念,感兴趣可以去查阅《数据结构》。


你将会获得:

                    1.如何使用js实现二叉查找树。

                    2.学会前、中、后序遍历。

                    3.了解相关实现原理


# 阅读时长>5min,可选择直接调试代码


*特点

    二叉查找树中序遍历后,得到的增序的排列方式。


*预览

以下封装的二叉查找树,包含了查找方法


function Node(data, left, right) { this.data = data; this.left = left; this.right = right;
}Node.prototype.show = function() { return this.data;}

function BST() {  this.root = null;}BST.prototype.insert = function (data) { var n = new Node(data, null, null); if (this.root == null) { this.root = n; } else { var current = this.root; var parent; while (true) { parent = current; if (data < current.data) { current = current.left; if (current == null) { parent.left = n; break; } } else { current = current.right; if (current == null) { parent.right = n; break; } } } }}
BST.prototype.inOrder = function(node) { // 中序遍历 if (!(node == null)) { inOrder(node.left); console.log(node.show() + ""); inOrder(node.right); }}
BST.prototype.preOrder = function(node) { // 先序 if (!(node == null)) { console.log(node.show() + ""); preOrder(node.left); preOrder(node.right); }}
BST.prototype.postOrder = function(node) { // 先序 if (!(node == null)) { postOrder(node.left); postOrder(node.right); console.log(node.show() + ""); }}
// 查找最小值
BST.prototype.getMin = function() { var current = this.root; while (current.left !== null) { current = current.left; } return current.data;}
// 查找最大值
BST.prototype.getMax = function() { var current = this.root; while (current.right !== null) { current = current.right; } return current.data;}
// 查找给定值BST.prototype.find = function(data) { var current = this.root; while (current != null) { if (current.data == data) { return current; } else if (data < current.data) { current = current.left; } else if (data > current.data) { current = current.right; } } return null;}


BST.prototype.remove = function(data) { this.root = this.removeNode(this.root, data); console.log(this.root,1)}
BST.prototype.removeNode = function(node, data) { if (node == null) { return null; } if (data == node.data) { // 没有子节点的节点 if (node.left == null && node.right == null) { return null; } // 没有左子节点的节点 if (node.left == null) { return node.right; } // 没有右子节点的节点 if (node.right == null) { return node.left; } // 查找最小节点 let getSmallest = function(node) { if (node.left === null && node.right == null) { return node; } if (node.left != null) { return node.left; } if (node.right !== null) { return getSmallest(node.right); }
} // 有两个子节点的节点 var tempNode = getSmallest(node.right); node.data = tempNode.data; node.right = this.removeNode(node.right, tempNode.data); return node; } else if (data < node.data) { node.left = this.removeNode(node.left, data); return node; } else { node.right = this.removeNode(node.right, data); return node; }}

中序排列

var nums = new BST(); nums.insert(23); nums.insert(45); nums.insert(16); nums.insert(37); nums.insert(3); nums.insert(99); nums.insert(22); console.log("Inorder traversal: "); nums.inOrder(nums.root);
> Inorder traversal: 3 16 22 23 37 45 99 // 增序



1.实现

二叉查找树是一种特殊的二叉树,相对较小的值保存在左节点中,较大的值保存在右节点。这一特性使得查找效率很高,对于数值型和非数值型的数据,比如单词和字符串都是如此。


// 节点function Node(data, left, right) {  this.data = data;  this.left = left;  this.right = right;  this.show = show;}Node.prototype.show = function() { return this.data;}

 1.1创建BST类

    BST 先要有一个 insert() 方法,用来向树中加入新节点。

首先要创建一个 Node 对象,将数据传入该对象保存。其次检查 BST 是否有根节点,如果没有,那么这是棵新树,该节点就是根节点,这个方法 到此也就完成了;否则,进入下一步。如果待插入节点不是根节点,那么就需要准备遍历 BST,找到插入的适当位置。该过程类 似于遍历链表。用一个变量存储当前节点,一层层地遍历 BST进入 BST 以后,下一步就要决定将节点放在哪个地方。找到正确的插入点时,会跳出循 环。查找正确插入点的算法如下。

(1) 设根节点为当前节点。

(2) 如果待插入节点保存的数据小于当前节点,则设新的当前节点为原节点的左节点;反 之,执行第 4 步。

(3) 如果当前节点的左节点为 null,就将新的节点插入这个位置,退出循环;反之,继续 执行下一次循环。

(4) 设新的当前节点为原节点的右节点。

(5) 如果当前节点的右节点为 null,就将新的节点插入这个位置,退出循环;反之,继续 执行下一次循环。

function Node(data, left, right) { this.data = data; this.left = left; this.right = right;
}Node.prototype.show = function() { return this.data;}

function BST() { this.root = null;}BST.prototype.insert = function (data) { var n = new Node(data, null, null); if (this.root == null) { this.root = n; } else { var current = this.root; var parent; while (true) { parent = current; if (data < current.data) { current = current.left; if (current == null) { parent.left = n; break; } } else { current = current.right; if (current == null) { parent.right = n; break; } } } }}

以上是最主要的,二叉查找树的js实现,其他方法简单描述一下



中序:就是先访问左子节点-->根节点-->右子节点



先序: 就是先访问根节点再访问子节点

js数据结构与算法(二叉树、二叉查找树)


后序:最后访问根节点

删除二叉树节点:

    删除节点主要分为,叶子节点,有左节点,有右节点,有两个子节点;

思路就是,

    1.找到要删除节点,判断是否含有子节点。

    2.如果没有子节点,便将该节点的值置为null。

        2.1有左/右节点,被删节点指向子节点。

        2.2含左右节点,(1)查找待删节点的左子树的最大值

                                 (2)查找待删节点的右子树的最小值

                                    将待删节点的值替换成以上(1)/(2)的值

  以下选的是(2)方案

BST.prototype.remove = function(data) { // 最后改变根节点值  this.root = this.removeNode(this.root, data);}//  返回的是node类型BST.prototype.removeNode = function(node, data) { if (node == null) { return null; } if (data == node.data) {  // 没有子节点的节点  if (node.left == null && node.right == null) { return null; }  // 没有左子节点的节点  if (node.left == null) { return node.right; }  // 没有右子节点的节点  if (node.right == null) { return node.left; }  // 查找最小节点 let getSmallest = function(node) { if (node.left === null && node.right == null) { return node; } if (node.left != null) { return node.left; } if (node.right !== null) { return getSmallest(node.right); }
} // 有两个子节点的节点 var tempNode = getSmallest(node.right); node.data = tempNode.data;    //  处理待删节点的右子树 node.right = this.removeNode(node.right, tempNode.data); return node; } else if (data < node.data) { node.left = this.removeNode(node.left, data); return node; } else { node.right = this.removeNode(node.right, data); return node; }}





-- 以上,欢迎斧正 --
前端划水笔记
探索前端开发的乐趣,里面有前端开发学习资源、经验博文......
4篇原创内容
Official Account