JS實現常見數據結構:二叉樹

緒論

樹的特點: 多層非線性數據結構。進行插入或搜索時很快。
樹的方法:

  1. add:向樹中插入一個節點。
  2. findMin:查找樹中最小的節點。
  3. findMax:查找樹中最大的節點。
  4. find:查找樹中某個節點。
  5. isPresent:判斷樹中是否存在某個節點。
  6. remove:移除樹中的某個節點。

正文

<!DOCTYPE html>
<div lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>index</title>
    <script src="js/jquery-2.2.4.min.js"></script>
    <style>
       
    </style>
</head>

<body>

</body>
<script>

    $(document).ready(function () {
        var tree = new MyTree();
        tree.add(9);
        tree.add(4);
        tree.add(15);
        tree.add(2);
        tree.add(3);
        tree.add(1);
        tree.add(6);
        tree.add(5);
        tree.add(8);
        tree.add(7);
        tree.add(17);
        tree.add(10);
        tree.add(11);

        tree.show();

        console.log('最小值' + tree.findMin());
        console.log('最大值' + tree.findMax());
        console.log('8是否存在' + tree.isPresent(8));
        tree.remove(1);
        console.log('最小值' + tree.findMin());
        tree.remove(9);
        console.log('9是否存在' + tree.isPresent(9));
        tree.show();

    });

    // 樹的節點信息
    function Node(data, left = null, right = null) {
        this.data = data;
        this.left = left;
        this.right = right;
    }

    function MyTree() {
        // 根節點
        this.root = null;

        // 向樹中插入一個節點
        this.add = function(v) {
            if (v === null || v === undefined) {
                return false;
            }

            var node = this.root;
            // 判斷根節點是否有值
            if (node === null) {
                this.root = new Node(v);
                return true;
            } else {
                var searchTree = function(n) {
                    // 與根節點進行比較
                    if (v < n.data) {
                        if (n.left === null) {
                            n.left = new Node(v);
                            return true;
                        } else {
                            return searchTree(n.left);
                        }
                    } else if (v > n.data) {
                        if (n.right === null) {
                            n.right = new Node(v);
                            return true;
                        } else {
                            return searchTree(n.right);
                        }
                    } else {
                        return false;
                    }
                };
                return searchTree(node);
            }
        };

        // 查找樹中最小的節點
        this.findMin = function() {
            var node = this.root;
            while(node.left !== null) {
                node = node.left;
            }
            return node.data;
        };

        // 查找樹中最大的節點
        this.findMax = function() {
            var node = this.root;
            while(node.right !== null) {
                node = node.right;
            }
            return node.data;
        };

        // 查找樹中某個節點
        this.find = function(v) {
            var node = this.root;
            while (node.data !== v) {
                if (v < node.data) {
                    node = node.left;
                } else {
                    node = node.right;
                }
                if (node === null) {
                    return null;
                }
            }
            return node;
        };

        // 判斷樹中是否存在某個節點
        this.isPresent = function(v) {
            var node = this.root;
            while (node !== null) {
                if (node.data === v) {
                    return true;
                }
                if (v < node.data) {
                    node = node.left;
                } else {
                    node = node.right;
                }
            }
            return false;
        };

        // 移除樹中的某個節點
        this.remove = function(v) {
            var removeNode = function(n, v) {
                if (n === null) {
                    return null;
                }
                if (v === n.data) {
                    // 沒有子節點
                    if (n.left === null && n.right === null) {
                        return null;
                    }
                    // 沒有左側子節點
                    if (n.left === null) {
                        return n.right;
                    }
                    // 沒有右側子節點
                    if (n.right === null) {
                        return n.left;
                    }
                    // 有兩個子節點,像刪除根節點一樣,去右側樹中找最小值,把這個最小值當成根節點,
                    // 再次調用刪除方法,把剛獲取的最小值在右側樹中刪除掉
                    var tempNode = n.right;
                    while (tempNode.left !== null) {
                        tempNode = tempNode.left;
                    }
                    n.data = tempNode.data;
                    n.right = removeNode(n.right, tempNode.data);
                    return n;
                } else if (v < n.data) {
                    n.left = removeNode(n.left, v);
                    return n;
                } else {
                    n.right = removeNode(n.right, v);
                    return n;
                }
            };
            this.root = removeNode(this.root, v);
        };

        // 展示
        this.show = function() {
            var arr = [];
            var myShow = function(n) {
                if (n !== null) {
                    arr.push(n.data);
                    if (n.left !== null) {
                        myShow(n.left);
                    }
                    if (n.right !== null) {
                        myShow(n.right);
                    }
                }
            };
            myShow(this.root);
            console.log(arr.join(' -> '));
        };
    }

</script>

</div>

結果

在這裏插入圖片描述
(若有什麼錯誤,請留言指正,3Q)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章