我有一个循环的链接列表,我想找出此列表中元素的总数。如何实现呢?
答案 0 :(得分:2)
我能想到的一种解决方案是维护两个指针。第一个指针(* start)将始终指向起始节点,例如节点A。 另一个指针(* current)将初始化为:current = start-> next。
现在,只需使用current-> next迭代每个节点,直到它指向开始。 并继续增加一个计数器:numberOfNodes ++;
代码如下:
public int countNumberOfItems(Node* start){
Node* current = start -> next;
int numberOfNodes = 1; //Atleast the starting node is there.
while(current->next != start){
numberOfNodes++;
current = current->next;
}
return numberOfNodes;
}
答案 1 :(得分:0)
您只想对链接列表中的节点计数吧?我在下面放一个例子。但是,在您的情况下,存在一个周期,因此,您还需要检测到该周期,以免多次计数某些节点。 我已经更正了我的答案,现在有一个普通的计数和循环计数(使用快速指针和慢速指针)。
static int count( Node n)
{
int res = 1;
Node temp = n;
while (temp.next != n)
{
res++;
temp = temp.next;
}
return res;
}
static int countInLoop( Node list)
{
Node s_pointer = list, f_pointer = list;
while (s_pointer !=null && f_pointer!=null && f_pointer.next!=null)
{
s_pointer = s_pointer.next;
f_pointer = f_pointer.next.next;
if (s_pointer == f_pointer)
return count(s_pointer);
}
return 0;
}
答案 2 :(得分:0)
比方说,列表在循环之前有x
个节点,在循环中有y
个节点。运行Floyd循环检测,计算慢步数s
。一旦检测到汇合点,请再次遍历循环以获取y
。
现在,从列表头开始,执行s - y
步,到达节点N
。最后,从N
和M
运行两个慢速指针,直到它们相遇为止,进行t
步骤。说服自己(或更好地证明)他们在列表的初始部分进入循环的地方相遇。
因此,初始部分具有s - y + t + 1
个节点,并且循环由y
个节点形成,总共有s + t + 1
个。
答案 3 :(得分:0)
首先使用弗洛伊德循环检测算法找到循环,并在检查循环后发现循环,并保持计数,然后打印相同的计数。
function LinkedList() {
let length = 0;
let head = null;
let Node = function(element) {
this.element = element;
this.next = null;
}
this.head = function() {
return head;
};
this.add = function(element) {
let node = new Node(element);
if(head === null){
head = node;
} else {
let currentNode = head;
while(currentNode.next) {
currentNode = currentNode.next;
}
currentNode.next = node;
}
};
this.detectLoopWithCount = function() {
head.next.next.next.next.next.next.next.next = head; // make cycle
let fastPtr = head;
let slowPtr = head;
let count = 0;
while(slowPtr && fastPtr && fastPtr.next) {
count++;
slowPtr = slowPtr.next;
fastPtr = fastPtr.next.next;
if (slowPtr == fastPtr) {
console.log("\n Bingo :-) Cycle found ..!! \n ");
console.log('Total no. of elements = ', count);
return;
}
}
}
}
let mylist = new LinkedList();
mylist.add('list1');
mylist.add('list2');
mylist.add('list3');
mylist.add('list4');
mylist.add('list5');
mylist.add('list6');
mylist.add('list7');
mylist.add('list8');
mylist.detectLoopWithCount();
答案 4 :(得分:0)
有一个“慢”指针,它一次移动一个节点。有一个“快速”指针,其移动速度快两倍,一次移动两个节点。
可视化的慢速指针和快速指针在具有10个节点的链表中移动:
1: |sf--------|
2: |-s-f------|
3: |--s--f----|
4: |---s---f--|
5: |----s----f|
在这一点上,有两件事是正确的:1)链表没有循环(用fast!= null && fast.next!= null检查)或2)确实循环了。让我们继续可视化,假设它确实循环了:
6: |-f----s---|
7: |---f---s--|
8: |-----f--s-|
9: |-------f-s|
10: s == f
如果链表未循环,则快速指针在O(n / 2)时间结束比赛;我们可以删除该常数并将其称为O(n)。如果链表确实循环,则慢速指针将在整个链表中移动,并最终在O(n)时间等于快速指针。