我有一个问题陈述,如:“如何在一次遍历中找到单链表的中间节点,而扭曲是我们不知道链表中的节点数?”
我有一个答案,比如“当你遍历链表并递增一个计数器直到你到达列表的末尾时,取一个向量并开始推送所有节点的地址”。所以最后我们可以得到列表中的节点数,如果是偶数(计数器/ 2)或奇数(计数器/ 2 +计数器%2)给出中间节点数,我们可以得到vectore.at(middlenodenumber)
指向中间节点“。
这很好......但这是浪费内存存储一个非常大的链表的所有地址!那么我们如何才能有更好的解决方案?
答案 0 :(得分:22)
以下是步骤:
*p1
和*p2
指向链接的头部
列表*p2
,2次(使用空检查)*p2
不为null,则增加*p1
1次*p2
达到null时;你有*p1
在中心[注意:如果处理容器类型链表,可以使用迭代器而不是指针]
答案 1 :(得分:10)
假设您有std::list<T> l
。
std::list<T>::iterator i = l.begin();
std::list<T>::iterator m = l.begin();
bool even = true;
while (i != list.end())
{
if (even) ++m;
++i;
even = !even;
}
现在m
指向l
的中间位置。
答案 2 :(得分:1)
您可以使用带有两个迭代器的单个循环,比如it1
和it2
,其中只在循环的每第二次迭代中递增it2
。 it1
到达列表末尾时终止。 it2
现在将指向列表的中间元素。
答案 3 :(得分:0)
试试这个:
你有2个指针。一个指向中间,另一个指向结尾,两个指向开始时列表的开头。每次第二次成功递增结束指针时,都会在一次中间递增,直到结束指针到达结尾。
答案 4 :(得分:0)
使用两个指针。将第一个指针移动两个节点,将第二个指针移动一个节点。当第一个指针到达结尾时,第二个指针将指向中间。
答案 5 :(得分:0)
// How to find the middle node of a single linked list in a single traversal
// 1. The length of the list is not given
// 2. If the number of nodes is even, there are two middle nodes,
// return the first one.
Node* MiddleNode(Node* const head)
{
if (!head)
{
return head;
}
Node* p1 = head, * p2 = head->next;
while (p2 && p2->next)
{
p1 = p1->next;
p2 = p2->next->next;
}
return p1;
}
答案 6 :(得分:0)
SLNode* mid(SLNode *head)
{
SLNode *one = head;
SLNode *two = head;
while(one != nullptr) {
one = one->next;
two = two->next;
if(one != nullptr) {
one = one->next;
//two = two->next;
}
}
return two;
}
试试这段代码