您的位置:首页 > 理论基础 > 数据结构算法

JS数据结构第五篇 --- 二叉树和二叉查找树

2019-08-19 00:51 1201 查看

一、二叉树的基本概念

从逻辑结构角度来看,前面说的链表、栈、队列都是线性结构;而今天要了解的“二叉树”属于树形结构。

//插入元素
function insertBST(element){
var node = new Node(element, null, null);

//根节点判断
if (root == null){
root = node;
}
else{ //非根节点
var current = root;
while(true){
if (element < current.element){ //往左节点方向放
if (current.left == null){
current.left = node;
break;
}
current = current.left;
}
else if (element > current.element){ //往右节点方向放
if (current.right == null){
current.right = node;
break;
}
current = current.right;
}
else { //相等,替换
current.element = element;
return;
}
}
}
size++;
}
View Code 2.2 二叉查找树的遍历,遍历有三种方式:中序、前序、后序

  中序指以升序的方式遍历所有节点;前序是指先访问根节点,再以同样的方式访问左子树和右子树;后序指的是先访问叶子节点,再从左子树到右子树,最后到根节点。

先看个效果图

//二叉树中序遍历:以升序方式访问二叉树中所有节点
function inOrder(){
return inOrderByNode(root);
}
function inOrderByNode(node){
if (node){
var str = "";
str += inOrderByNode(node.left);
str += node.element + ", ";
str += inOrderByNode(node.right);
return str;
}
return "";
}

//前序遍历:先访问根节点,再访问左子树和右子树
function preOrder(){
return preOrderByNode(root);
}
function preOrderByNode(node){
if (node){
var str = '';
str += node.element + ", "; //先访问根节点
str += preOrderByNode(node.left); //再访问左子树
str += preOrderByNode(node.right); //再访问右子树
return str;
}
return "";
}

//后序遍历:先访问叶子节点,再左子树,再右子树,再到根节点
function postOrder(){
return postOrderByNode(root);
}
function postOrderByNode(node){
if (node){
var str = "";
str += postOrderByNode(node.left);
str += postOrderByNode(node.right);
str += node.element + ", ";
return str;
}
return "";
}
View Code  

2.3 查找二叉查找树的最大值、最小值、是否存在某个值

最大值:因为较大的值都是在右子树上,则最大值一定是在右子树的最后一个节点上;

最小值:较小的值都是在左子树上,则最小值一定在左子树的最后一个节点上;

是否存在某个值,则是遍历查找

//查找最小值:因为较小的值都在左边,所以最小值一定是左子树的最后一个节点
function getMin(){
var minNode = getMinNode(root);
if (minNode) {
return minNode.element;
}
return null;
}
//查找最小节点
function getMinNode(node){
var current = node;
while(current){
if (current.left == null){
return current;
}
current = current.left;
}
return null;
}

//查找最大值:因为较大的值都在右边,所以最大值一定是在右子树的最后一个节点
function getMax(){
var maxNode = getMaxNode(root);
if (maxNode){
return maxNode.element;
}
return null;
}
//查找最大节点
function getMaxNode(node){
var current = node;
while(current){
if (current.right == null){
return current;
}
current = current.right;
}
return null;
}

//查找指定值,是否存在这个元素
function isExist(element){
var current = root;
while(current){
if (element < current.element){ //左子树寻找
current = current.left;
}
else if (element > current.element){ //右子树寻找
current = current.right;
}
else{ //存在
return true;
}
}
return false;
}
View Code

 

2.4 删除二叉查找树中的指定元素

从二叉查找树上删除节点的操作最复杂,其复杂程度取决于删除哪个节点。如果删除没有子节点 的节点,那么非常简单。如果节点只有一个子节点,不管是左子节点还是右子节点,就变 得稍微有点复杂了。删除包含两个子节点的节点最复杂。

//删除元素
function remove(element){
root = removeNode(root, element);
}
function removeNode(node, element){
if (node == null) {
return null;
}

if (node.element == element){
size--;
//node没有左子树
if (node.left == null){
return node.right;
}
else if (node.right == null){ //node没有右子树
return node.left;
}
/**
* node有左子树和右子树,这个时候要找出最接近node节点值的节点
* 1、如果找出比node节点的element稍大的节点,则从node右节点的最小节点
* 2、如果找出比node节点的element稍小的节点,则从node左节点的最大节点
*/
//第一种方式,找出比node的element稍微大点的节点
var minNode = getMinNode(node.right);
node.element = minNode.element;
node.right = removeNode(node.right, minNode.element);

// //第二种方式, 找出比node的element稍微小点的节点
// var maxNode = getMaxNode(node.left);
// node.element = maxNode.element;
// node.left = removeNode(node.left, maxNode.element);

return node;
}
else if(element < node.element){ //往左子树方向继续找
node.left = removeNode(node.left, element);
return node;
}
else{
//往右子树方向继续找
node.right = removeNode(node.right, element);
return node;
}
}
View Code

 

完整demo见:https://github.com/xiaotanit/Tan_DataStruct

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: