【发布时间】:2015-12-01 23:08:10
【问题描述】:
我使用 Javascript 编写了一个循环链表并检测和删除循环。在循环检测部分之前它工作正常。它如何无法删除循环节点。更具体地说:此代码的 removeLoop 功能不起作用。
这是我的代码:
function Node(element){
this.element = element;
this.next = null;
}
//circular linked list class
function LList() {
this.head = new Node("head");
this.head.next = this.head;
this.find = find;
this.insert = insert;
this.display = display;
}
function find(item){
var curr = this.head;
while(curr.element != item){
curr = curr.next;
}
return curr;
}
//inserting items into linked list
function insert(newElem, after){
var newNode = new Node(newElem);
var curr = this.find(after);
newNode.next = curr.next;
curr.next = newNode;
}
function display() {
var currNode = this.head;
while ((currNode.next !== null) &&
(currNode.next.element !== "head")) {
console.log(currNode.next.element);
currNode = currNode.next;
}
}
function findPrevious(item){
var curr = this.head;
while(curr.next !== null && curr.next.element !== item){
curr =curr.next;
}
return curr;
}
//creating a linkedlist object
var furniture = new LList();
furniture.insert("chair","head");
furniture.insert("table", "chair");
furniture.insert("couch", "table");
furniture.insert("stool","couch");
//furniture.display();
//detecting if a linked list is circular
function detectALoop(list){
var slow = list.head;
var fast = list.head;
while(slow && fast && fast.next){
slow = slow.next;
fast = fast.next.next;
if(slow === fast){
removeLoop (slow, list);
return 1;
}
}
return 0;
}
//This part of the code doesnot work
function removeLoop(loopNode, list)
{
var ptr1 = loopNode;
var ptr2 = loopNode;
var looplen = 1,i;
// count the number of nodes in loop
while(ptr1.next != ptr2)
{
ptr1 = ptr1.next;
looplen++;
}
console.log(looplen)
ptr1 = list.head;
ptr2 = list.head;
for(i=0; i <= looplen; i++)
{
ptr2 = ptr2.next;
}
while(ptr2.next != ptr1.next)
{
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
ptr2.next = null; // breaking the loop
}
console.log(detectALoop(furniture))
furniture.display();
【问题讨论】:
-
列表是一个循环是您设计的一部分吗?有没有办法最后一个节点会指向中间?如果没有,我认为可以删除很多内容。例如,列表不需要对头节点的两个引用,而是将节点存储在末尾。这使得这非常简单。 ..
-
我的代码,在 LList 类中:this.head = new Node("head"); this.head.next = this.head;这是为了使列表循环。当我检查循环是否是循环时,我得到了真实的结果。在我的情况下,循环位于列表的开头。我正在尝试删除循环节点,我需要一个通用算法,无论循环在哪里,它都可以工作。
-
好的,如果最后一个节点指向列表的中间,这是否需要工作?我仍然认为循环比你需要的多。
-
考虑使用双链表来加快查找上一个项目。
标签: javascript algorithm linked-list