Javascript数据结构算法之二叉查找树BST(构造,遍历,查找,删除,计数)

树是一种非线性的数据结构,以分层的方式存储数据。树被用来存储具有层级关系的数据。树可以分为几层,根节点是第0层,我们定义树的层数就是树的深度。

二叉树是一种特殊的树,它的子节点个数不超过两个。二叉查找树(BST)是一种特殊的二叉树,相对较小的值保存在左节点中,较大的值保存在右节点中。在二叉树查找上进行查找非常快,为二叉树添加或删除元素非常快。

BST的JS实现

网页展示

《Javascript数据结构算法之二叉查找树BST(构造,遍历,查找,删除,计数)》

代码部分

1.构造

//BST.js
//包含两个类,Node()存储节点,BST()存储树。
function Node(data, left, right) {
    this.data = data;
    this.count = 1;
    this.left = left;
    this.right = right;
    this.show = show;//显示节点数据
    this.update = update;//计数功能
}
function show(){
    return this.data;
}
function update(){
    return ++this.count;
}
function BST(){
    this.root = null;
    this.knots = 0;//记录节点个数
    this.insert = insert;//插入操作
    this.find = find;//查找操作
    this.getMin = getMin;
    this.getMax = getMax;
    this.remove = remove;//删除操作
    this.countKnots = countKnots;//返回节点个数
    this.countEdges = countEdges;//返回边个数
}

2.插入

//BST.js
function insert(data){
    var n = new Node(data, null, null);//新建包含该数据的节点
    this.knots++;
    if(this.root == null)
    {
        this.root = n;
    }
    else
    {
        var current = this.root;
        while(true)
        {
            //如果待插入节点的数据小于当前节点,则设置其左节点为当前节点
            if(data<current.data)
            {
                //如果当前节点的左节点为空,就将新的节点插入这个位置
                if(current.left == null)
                {
                    current.left = n;
                    break;
                }
                current = current.left;
            }
            //如果待插入节点的数据大于或者等于当前节点,则设置其右节点为当前节点
            else{
                //如果当前节点的右节点为空,就将新的节点插入这个位置
                if(current.right == null)
                {
                    current.right = n;
                    break;
                }
                current = current.right;
            }
        }
    }
}

3. 遍历

有三种遍历:中序,先序和后序。使用递归的方法最容易实现。

//BST.js
//中序遍历按照节点上的键值,以升序访问所有节点
function inOrder(node){
    var instr = "";
    if(!(node == null)){
        inOrder(node.left);
        instr += node.show()+" ";
        inOrder(node.right);
    }
    return instr;
}
//先序遍历先访问根节点,然后以相同的方式访问左子树和右子树
function preOrder(node){
    var prestr = "";
    if(!(node == null)){        
        prestr += node.show()+" ";
        preOrder(node.left);
        preOrder(node.right);
    }
    return prestr;
}
//后序遍历先访问叶子节点,然后以相同的方式访问左子树和右子树
function postOrder(node){
    var poststr = "";
    if(!(node == null)){
        postOrder(node.left);
        postOrder(node.right);
        poststr += node.show()+" ";
    }
    return poststr;
}

4. 删除

function remove(data){
    this.root = removeNode(this.root, data);
    this.knots--;
}

//该方法中使用了递归操作
function removeNode(node, data) {
    if(node == null)
    {
        return null;
    }
    //巧了!待删除的数据刚好是这个节点
    if(data == node.data){
        //如果左右皆空,直接删除
        if(node.left == null && node.right == null)
        {
            node = null;
        }
        //如果左空,将其右子树移过来
        else if(node.left == null)
        {
            node = node.right;
        }
        //如果右空,将其左子树移过来
        else if(node.right == null)
        {
            node = node.left;
        }
        //如果左右都不空,将右子树的最小值移到该节点
        else{
            var temp = getSmallest(node.right);
            node.data = temp;
            node.right = removeNode(node.right, temp);
        }
    }
    //不巧!!!待删除的数据不是该节点,那一定在该节点的左子树或者右子树上
    else if(data < node.data){
        node.left = removeNode(node.left, data);
    }
    else{
        node.right = removeNode(node.right, data);
    }
    //因为所有改动都是在当前节点node上进行的,所以直接返回node即可
    return node;
}
function getSmallest(node){
    if(node == null)
    {
        //空树
    }
    while(!(node.left == null)){
        node = node.left;
    }
    return node.data;
}

5.查找

//找最左边那个值
function getMin(){
    var current = this.root;
    if(current == null)
    {
        //空树
    }
    while(!(current.left == null)){
        current = current.left;
    }
    return current.data;
}
//找最右边那个值
function getMax(){
    var current = this.root;
    if(current == null)
    {
        //空树
    }
    while(!(current.right == null)){
        current = current.right;
    }
    return current.data;
}

function find(data){
    var current = this.root;
    while(current != null)
    {
        if(data == current.data)
            return current;
        else if(data < current.data)
            current = current.left;
        else
            current = current.right;
    }
    return null;
}

6. 其它

function countKnots(){
    return this.knots;
}
function countEdges(){
    return this.knots-1;
}

BST计数

计数是指记录一组数据中某数据出现的次数。

网页展示

《Javascript数据结构算法之二叉查找树BST(构造,遍历,查找,删除,计数)》

代码部分

<!-- index.html-->

<!DOCTYPE html>
<html>
<head>
    <title>JS structure - BST</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="BST.js" type="text/javascript"></script>
    <script src="app.js" type="text/javascript"></script>
</head>
<style> #element { width: 60%; margin: 30px auto; padding: 10px; border: 1px solid #333; } label { font-style:normal; font-size:16px; } </style>
<body>
    <div id="element">
        <h2>计数<h2>
        <label for="num_of_grades">输入成绩个数:</label>
        <input type="text" id="num_of_grades" />
        <input type="button" value="随机生成成绩:" onclick="getGrades()" />
        <textarea id="bst_grades"></textarea>
        <div>
        <label for="num_of_grades">查询获得该成绩的人数:</label>
        <input type="text" id="num_of_certain_grade" />
        <input type="button" value="计数:" onclick="BSTcount()" />
        <textarea id="bst_count"></textarea>
        </div>
    </div>
</body>
</html>
//app.js
var gradesArr = [];
function getGrades(){
    //随机获得一组成绩数据
    var gradesNum = parseInt(document.getElementById("num_of_grades").value,10);
    for(var i=0; i<gradesNum; i++)
    {
        gradesArr[i] = Math.floor(Math.random()*61+40);
    }
    //在网页上显示该组数据
    var result = document.getElementById("bst_grades");
    result.innerHTML = gradesArr;
}
function BSTcount(){
    //将这组成绩数据插入到二叉查找树中
    var grades = new BST();
    for(var i=0; i<gradesArr.length; i++)
    {
        var currGrade = gradesArr[i];
        var currNode = grades.find(currGrade);
        if(currNode==null)
            grades.insert(currGrade);
        else
            //如果遇到重复数据,则将该节点的count属性+1
            currNode.update();
    }
    //输入待查找的成绩
    var certainGradeNum = parseInt(document.getElementById("num_of_certain_grade").value,10);
    //在网页上显示该得分的人数
    var str="";
    if(grades.find(certainGradeNum) == null)
        str = "没有人得到"+certainGradeNum+"分。";
    else
        str = grades.find(certainGradeNum).count+"人得到"+certainGradeNum+"分。";

    var result = document.getElementById("bst_count");
    result.innerHTML = str;
}
    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/u011376293/article/details/69566957
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞