簡體   English   中英

為JavaScript二進制搜索樹編寫遞歸添加方法

[英]Writing a recursive add method for a Javascript Binary Search Tree

我正在嘗試為JS中的BST寫一個add / insert方法,但是由於某種原因似乎無法使其工作。 我的代碼在這里:

function Node(value) {
    this.value = value;
    this.left = null;
    this.right = null;
}


function BinarySearchTree() {
    this.root = null;

    this.add = function(insertElem){
        let currNode = this.root;

        var recurInsert = function(elem, node){
            if(node == null){
                let newNode = new Node(elem);
                node = newNode;
                console.log("firstNode");
                return undefined;
            }
            else if(elem == node.value){
                console.log("equal val");
                return null
            }
            else if(elem > node.value){
                console.log("go right");
                recurInsert(elem, node.right);
            }
            else{
                console.log("go left");
                recurInsert(elem, node.left);
            }
        }

        recurInsert(insertElem, currNode);
    }
}

具體來說,line node = newNode實際上並沒有將node設置為newNode 我懷疑這可能與JavaScript的按值傳遞性質有關,但我不確定。

我哪里做錯了?

另外,如果可能的話,我希望暫時保留這種遞歸形式。

問題是您需要將node.right或node.left設置為newNode而不是node = newNode。 否則,將沒有引用的鏈接,並且您的根永遠不會有任何子代。

因此,如果right.next或left.next為null,則應該在此處實際插入,而不是在下一個遞歸中。

      else if(elem > node.value){
            console.log("go right");
            if (node.right == null) 
                 node.right = new Node(elem);
            else 
                recurInsert(elem, node.right);
        }
        else{
            console.log("go left");
            if (node.left == null)
                node.left = new Node(elem);
            else 
                recurInsert(elem, node.left);
        }

您還可以刪除整個if (node == null) { ... }部分,並只需在啟動前檢查root是否為null一次

if (root == null) {
   root = new Node(insertElem);
   return null;
}

這是完整的代碼:

    function Node(value) {
        this.value = value;
        this.right = null;
        this.left = null;
}

function BinarySearchTree() {
    this.root = null;

    this.add = function(value) {
        if (this.root == null) {
            this.root = new Node(value);
            return;
        } 
        var recInsert = function(value, node) {
            if (value == node.value) {
                print("equal");
                return;
            }
            if (value < node.value) {
                if (node.left == null) 
                    node.left = new Node(value);   
                else 
                    recInsert(value, node.left);
            }
            else {
                if (node.right == null) 
                    node.right = new Node(value);   
                else 
                    recInsert(value, node.right);
            }
        }
        recInsert(value, this.root);
    } 

    this.print = function() {
        if (this.root != null) {
           var rec = function(node) {
               if (node == null) 
                   return;
               rec(node.left);
               print(node.value);
               rec(node.right);
           }
           rec(this.root);
        }   
    }
}

基本上,您需要將對象引用移交給遞歸函數,因為如果不這樣做,則無需鏈接到根節點就可以創建新節點。

該代碼以對象和方向為鍵,並檢查要做出的四個不同的決定。 如果必須分配新節點,則使用對象和密鑰。

如果值小於或大於節點的值,則將節點與新方向一起使用以進行檢查。

 function Node(value) { this.value = value; this.left = null; this.right = null; } function BinarySearchTree() { this.root = null; this.add = function (value) { function check(node, direction) { if (node[direction] === null) { node[direction] = new Node(value); console.log('new node', value); return; } if (node[direction].value === value) { console.log('equal value', value); return; } if (node[direction].value > value) { console.log('go left', node[direction].value); check(node[direction], 'left'); return; } if (node[direction].value < value) { console.log('go right', node[direction].value); check(node[direction], 'right'); } } check(this, 'root'); }; } var tree = new BinarySearchTree; tree.add(10); tree.add(5); tree.add(15); tree.add(2); tree.add(4); tree.add(11); console.log(tree); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

通過使用默認節點的更短方法。

 function Node(value) { this.value = value; this.left = null; this.right = null; } function BinarySearchTree() { this.root = null; this.add = function (value) { function check(node) { if (node.value === value) { return; } if (node.value > value) { check(node.left = node.left || new Node(value)); return; } if (node.value < value) { check(node.right = node.right || new Node(value)); } } check(this.root = this.root || new Node(value)); }; } var tree = new BinarySearchTree; tree.add(10); tree.add(5); tree.add(15); tree.add(2); tree.add(4); tree.add(11); console.log(tree); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

更改對象與屬性的小例子

 function assign(o) { // take object reference as value of o o = { bar: 43 }; // assign a new value to o, object keeps it value console.log('o', o); // the reference to object is replaced by an own object } function change(o) { // take object reference as value of o o.bar = 41; // take object reference and assign a new property console.log('o', o); // because of the object reference, o and object has changed } var object = { foo: 42 }; console.log('object', object); assign(object); console.log('object', object); change(object); console.log('object', object); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM