问题:有没有办法在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;
}
}