Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何查找链表中的项目总数?_Algorithm_Data Structures_Linked List_Floyd Cycle Finding - Fatal编程技术网

Algorithm 如何查找链表中的项目总数?

Algorithm 如何查找链表中的项目总数?,algorithm,data-structures,linked-list,floyd-cycle-finding,Algorithm,Data Structures,Linked List,Floyd Cycle Finding,我有一个循环的链表,我想找出这个链表中元素的总数。如何实现这一点?您只想对链接列表中的节点进行计数,对吗?我在下面举了一个例子。但在您的情况下,存在一个循环,因此您还需要检测该循环,以避免多次计算某些节点。 我已经更正了我的答案,现在有一个普通的计数和循环中的计数(使用快速和慢速指针) 假设列表在循环之前有x节点,在循环中有y节点。运行Floyd循环检测,计算慢速步数,s。一旦检测到一个交汇点,再次绕着循环运行,以获得y 现在,从列表头开始,执行s-y步骤,到达节点N。最后,从N和M运行两个慢速

我有一个循环的链表,我想找出这个链表中元素的总数。如何实现这一点?

您只想对链接列表中的节点进行计数,对吗?我在下面举了一个例子。但在您的情况下,存在一个循环,因此您还需要检测该循环,以避免多次计算某些节点。 我已经更正了我的答案,现在有一个普通的计数和循环中的计数(使用快速和慢速指针)


假设列表在循环之前有
x
节点,在循环中有
y
节点。运行Floyd循环检测,计算慢速步数,
s
。一旦检测到一个交汇点,再次绕着循环运行,以获得
y

现在,从列表头开始,执行
s-y
步骤,到达节点
N
。最后,从
N
M
运行两个慢速指针,直到它们相遇,执行
t
步骤。说服自己(或者更好地证明)他们在列表的初始部分进入循环的地方相遇


因此,初始部分有
s-y+t+1
节点,循环由
y
节点组成,给出了
s+t+1
总数。

我能想到的一个解决方案是维护两个指针。第一个指针(*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; 
}

首先使用Floyd循环检测算法查找循环,并在检查循环时保持计数(一旦找到循环),然后打印相同的计数

函数链接列表(){
设长度=0;
设head=null;
让节点=函数(元素){
this.element=元素;
this.next=null;
}
this.head=函数(){
回流头;
};
this.add=函数(元素){
让节点=新节点(元素);
if(head==null){
头部=节点;
}否则{
设currentNode=head;
while(currentNode.next){
currentNode=currentNode.next;
}
currentNode.next=节点;
}
};
this.detectLoopWithCount=函数(){
head.next.next.next.next.next.next.next=head;//循环
设fastPtr=头部;
让slowPtr=头部;
让计数=0;
while(slowPtr&&fastPtr&&fastPtr.next){
计数++;
slowPtr=slowPtr.next;
fastPtr=fastPtr.next.next;
if(slowPtr==fastPtr){
找到console.log(“\n宾果:-”)循环..!!\n”);
log('元素总数=',计数);
返回;
}
}
}
}
让mylist=newLinkedList();
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()有一个“慢”指针,一次移动一个节点。有一个“快速”指针,移动速度是原来的两倍,一次移动两个节点

当慢速和快速指针在包含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)时间等于较快的指针。

您使用的语言是什么?简单的解决方法:您可以在向链表添加节点时添加计数器。请用您使用的语言详细说明您的问题?谷歌“弗洛伊德的周期检测算法”。这取决于:您的问题是关于,或关于?由于链表处于循环中,临时值将不会为空。请阅读问题中提到的OP还应在循环中设置
current=current->next
,以在每一步更新当前指针。谢谢@Jonaswg。使用修复程序更新了它。可能会添加“起始节点”可以是列表中的任何节点。为什么不让
s
指针保持静止;它的工作量更少,
f
会更快地找到它。当循环有奇数计数时,您的算法还应注意不要让
f
跳过
s
。如果我们保持s指针静止,我们能在循环中找到循环吗?甚至我们能找到循环是否被创建?我的问题是:所有节点都是循环的一部分。但也许你的假设是正确的。但是你仍然应该回答“如何找到项目总数”的问题。。。
6: |-f----s---|
7: |---f---s--|
8: |-----f--s-|
9: |-------f-s|
10: s == f