Проблема: есть ли способ использовать TreeListNode в Tree.insert (элемент)?Ограничение состоит в том, что singleLinkedList.addToTail (element) принимает элемент и возвращает ListNode, у которого нет атрибутов 'children' и 'parent', и если я сначала создам TreeListNode (element), то я не смог бы использовать singleLinkedList.addToTail (element).
Контекст: я изучаю структуры данных в javascript.Уже реализовав LinkedList и Queues, я сейчас пытаюсь использовать их как библиотеку для реализации n-арного дерева с обходами в глубину и в ширину. Благодаря этому я также пытаюсь изучить лучшие практики javascript.Любой, кто может предложить дополнительные советы о том, как улучшить мой код, получит мою вечную благодарность.Является ли шаблон, которому я следовал (в отношении использования объектов Position, ListNode и TreeListNode), в порядке?Правильно ли я следовал «составлению по наследованию»?
Вот моя реализация дерева:
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;
}
}