Javascript樹(一):廣度遍歷和深度遍歷

kkkkuuuu發表於2017-12-27

#文章關鍵點 ###1. 樹的建立 ###2. 深度遍歷和廣度遍歷 ###3.callback回撥函式 ###4. 遍歷方式查詢新增刪除等介面

1.樹的建立

一個節點有三個部分組成

  • data 儲存資料

  • parent 指向的父節點

  • children 孩子節點

    function Node(data){ this.data = data; this.parent = null; this.children = [ ]; }

    function Tree(node){ var node = new Node(data); this._root = node; }

    var tree = new Tree('CEO'); // {data: 'CEO', parent: null, children: []} tree._root;

2.(a) 深度遍歷(DSF)

Tree.prototype.traverseDF = function (callback) {  
        (function recurse(currentNode) {  
            for(let i=0;i<currentNode.children.length;i++){
                recurse(currentNode.children[i]);
            }
            callback(currentNode);
        })(this._root);
    }
複製程式碼

eg:

var tree = new Tree('one');

tree._root.children.push(new Node('two'));
tree._root.children[0].parent = tree;

tree._root.children.push(new Node('three'));
tree._root.children[1].parent = tree;

tree._root.children.push(new Node('four'));
tree._root.children[2].parent = tree;

tree._root.children[0].children.push(new Node('five'));
tree._root.children[0].children[0].parent = tree._root.children[0];

tree._root.children[0].children.push(new Node('six'));
tree._root.children[0].children[1].parent = tree._root.children[0];

tree._root.children[2].children.push(new Node('seven'));
tree._root.children[2].children[0].parent = tree._root.children[2];

/*

creates this tree

 one
 ├── two
 │   ├── five
 │   └── six
 ├── three
 └── four
     └── seven

*/
複製程式碼

2.(b)廣度遍歷(利用queue)

    Tree.prototype.traverseBF = function (callback) {
        var queue = new Queue();
        queue.enqueue(this._root);
        var currentTree = queue.dequeue();
        while(currentTree){
            for(let i =0;i<currentTree.children.length;i++){
                queue.enqueue(currentTree.children[i]);
            }
            callback(currentTree);
            currentTree = queue.dequeue();
        }
      }
複製程式碼

callback 預設為一個函式,使得在函式內能呼叫其它函式

tree.traverseDF(function(node) {
        console.log(node.data)
    });

    /*
     
    logs the following strings to the console
     
    'five'
    'six'
    'two'
    'three'
    'seven'
    'four'
    'one'
     
    */
複製程式碼
  1. 遍歷方式查詢新增刪除等介面

#####a.遍歷方式 Tree.prototype.contains = function (callback,traversal) { traversal.call(this,callback); } eg:

//tree is an example of a root node
tree.contains(function(node){
  if (node.data === 'two') {
      console.log(node);
  }
}, tree.traverseBF);
複製程式碼

#####b.查詢

  // tree is an example of a root node
tree.contains(function(node){
    if (node.data === 'two') {
        console.log(node);
    }
}, tree.traverseBF);
複製程式碼

#####c.新增 Tree.prototype.add = function(data, toData, traversal) { var child = new Node(data), parent = null, callback = function(node) { if (node.data === toData) { parent = node; } };

  this.contains(callback, traversal);//不要忘記回撥查詢

  if (parent) {
    parent.children.push(child);
    child.parent = parent;
  } else {
    throw new Error('Cannot add node to a non-existent parent.');
  }
};
複製程式碼

eg:

var tree = new Tree('CEO');
tree.add('VP of Happiness', 'CEO', tree.traverseBF);

/*
our tree
'CEO'
└── 'VP of Happiness'
*/
複製程式碼

#####d.刪除 Tree.prototype.remove = function(data, fromData, traversal) { var tree = this, parent = null, childToRemove = null, index;

        var callback = function(node) {
            if (node.data === fromData) {
                parent = node;
            }
        };

        this.contains(callback, traversal);

        if (parent) {
            index = findIndex(parent.children, data);

            if (index === undefined) {
                throw new Error('Node to remove does not exist.');
            } else {
                childToRemove = parent.children.splice(index, 1);
            }
        } else {
            throw new Error('Parent does not exist.');
        }

        return childToRemove;
    };
複製程式碼

相關文章