通过链接列表在javascript中实现n-ary树

时间:2018-05-17 09:48:43

标签: javascript linked-list tree depth-first-search breadth-first-search

  • 问题:有没有办法在Tree.insert(element)中使用TreeListNode?约束是singleLinkedList.addToTail(element)接受一个元素并返回一个ListNode,它没有' children'和父母'属性,如果我先构造TreeListNode(element),那么我将无法使用singleLinkedList.addToTail(element)。

  • 上下文:我正在学习javascript中的数据结构。已经实现了LinkedList和Queues,我现在尝试将它们用作库来实现具有Depth-first和广度优先遍历的n-ary树。通过这个,我也尝试学习javascript最佳实践。如果能够就如何进一步改进我的代码提出进一步的建议,那么我将永远感激不尽。我遵循的模式(关于使用Position,ListNode和TreeListNode对象)是否正常?我是否正确地遵循了#34;构成而非继承"?

这是我的Tree实现:

const Queue = require('./queue.js')
const LinkedListLibrary = require('./linkedListTest.js');

function TreeNode(element){
    LinkedListLibrary.ListNode.call(this, element);
    this.parent = null;
    this.children = new LinkedListLibrary.SingleLinkedList() 
}

TreeNode.prototype = Object.create(LinkedListLibrary.ListNode.prototype)

function Tree(rootElement){
    this._root = new TreeNode(rootElement);     
    this._size = 1;
};

Tree.prototype = {

    isEmpty: function() {
        return (this._size == 0)
    //Returns true if the tree is empty. True only initially
    },

    size: function() {
        return this._size
    // Returns the number of nodes in the tree. 
    },

    getRoot: function(){
        //console.log("Entered getRoot function");
        return this._root
    },

    traverseDF: function(callback){
    // This method traverses a tree with depth-first search.
        (function recurse(currentNode){ //Step 2    
            for (var i = 0; i < currentNode.children.length; i++){
                recurse(currentNode.children.getNode(i)) //Step 3. When currentNode = leaf, length = 0
        };
        //console.log("Traversed the children of: " + JSON.stringify(currentNode.getElement()));
        callback(currentNode) //Step 4

    })(this.getRoot()) //Step 1. Immediate Invoke Recurse with the root node as argument

    },

    traverseBF: function(callback){
        var bfQueue = new Queue();
        bfQueue.enqueue(this.getRoot());
        while(!bfQueue.isEmpty()){   
            console.log("Next element to dequeue:" + bfQueue._head.data.getElement())
            var currentTreeNode = bfQueue.dequeue();
            console.log("currentTreeNode contains " + currentTreeNode.getElement())
            callback(currentTreeNode)
            for (var i = 0; i < currentTreeNode.children.length; i++){
                var temp = currentTreeNode.children.getNode(i);
                console.log("enqueing: " + JSON.stringify(temp.getElement()))
                bfQueue.enqueue(temp);

            }

        }

    },

    insert: function(element, toElement, traversal) {
        //Adds a node to a tree.
        console.log("Inserting element: " + element)
        var parent = null
        var callback = function(node){
        //console.log("Now comparing: " + node.getElement())
            if (node.getElement() === toElement ){
                //console.log(JSON.stringify("Found parent: " + node.getElement())   );
                parent = node;
            }
        }
        traversal.call(this, callback);

        if(parent){
            //console.log("Adding to tail: " + JSON.stringify(data));
            var childrenList = parent.children
            childrenList.addToTail(element);
            var newChild = childrenList.getNode(childrenList.length-1)
            newChild.parent = parent;
            //console.log(JSON.stringify("Added new child to " + parent.getElement() + " with element " + newChild.getElement())  );
        } else {
            throw new Error('cannot add node to a non-existent parent')
          }

     }

这是LinkedList实现:

module.exports = { Position, ListNode, SingleLinkedList} 

function Position(element){
    this._element = element
}

Position.prototype.getElement = function(){
    return this._element
}   

function ListNode(element, next){
    this.next = next,
    Position.call(this, element)
}

ListNode.prototype = Object.create(Position.prototype)

function SingleLinkedList(){
    this.head =  null;  
    this.length = 0;
}

SingleLinkedList.prototype = {

    addToHead : function(element){
        var newHead = new ListNode(element, this.head);
        this.head = newHead;
        this.length++
    },

    addToTail : function(element){
        var newNode = new ListNode(element, null);
        if (this.head === null){
            //console.log("Head not found, adding to head")
            this.head = newNode;
            this.length++;
        return;
       }
       var current_node = this.head;
       while(!(current_node.next === null)){
           current_node = current_node.next
       }
        current_node.next = newNode;
        this.length++
    },

    getNode : function(position){
        if (position >= this.length) {
            console.log("Position out of bounds")
        }
        var nodeToCheck = this.head;
        //console.log("Checking node: " + nodeToCheck.getElement())
        var i = 0;
        while(i != position) {
            nodeToCheck = nodeToCheck.next;
            //console.log("New nodeToCheck: " + nodeToCheck.getElement())
            i++;
        }
        return nodeToCheck;
    }
}

0 个答案:

没有答案