链表错误的中间
Middle of a linked list bug
我写了一个函数来打印单向链表的中间,但是当列表长度为奇数时,它不会打印它(不打印任何只是空格的东西(,当列表长度是偶数时,它打印的是mid(节点的总和,这是正确的(。
我有以下代码:
struct Node {
int value;
Node* next;
};
Node* head = NULL;
void insert_element2(int x);
void mid_list(Node* head);
int main() {
insert_element2(1);
insert_element2(2);
insert_element2(3); //etc
mid_list(head);
return 0;
}
void insert_element2(int x) {
Node* temp1 = new Node();
temp1->value = x;
temp1->next = NULL;
if (head == NULL)
head = temp1;
else {
Node* temp2 = head;
while(temp2->next != NULL) {
temp2 = temp2->next;
}
temp2->next = temp1;
}
}
void mid_list(Node* head) {
Node* temp1 = head;
Node* temp2 = head;
while (temp1->next != NULL) { **// When i change "temp->next" with "temp" is acting opposite(even/odd)**
temp1 = temp1->next->next;
temp2 = temp2->next;
}
cout << temp2->value;
}
让我们逐步了解奇数大小列表示例的逻辑:
-
进入
mid_list()
后,head
是value=1
节点,temp1
和temp2
设置为head
。 请注意,您没有检查head
的NULL
,因此如果列表为空,您的代码将失败,但此示例中并非如此。 -
在第一次循环迭代中,
temp1->next
不是NULL
,因此temp1
设置为temp1->next->next
哪个是value=3
节点,temp2
设置为temp2->next
哪个是value=2
节点。 -
在第二次循环迭代中,
temp1->next
是NULL
的,因此循环中断,value=2
节点被打印出来(不是你声称的空白(。目前为止,一切都好。
现场演示
现在,让我们逐步了解偶数大小列表的逻辑:
-
进入
mid_list()
后,head
是value=1
节点,temp1
和temp2
设置为head
。 -
在第一次循环迭代中,
temp1->next
不是NULL
,因此temp1
设置为temp1->next->next
哪个是value=3
节点,temp2
设置为temp2->next
哪个是value=2
节点。 -
在第二次循环迭代中,
temp1->next
不是NULL
,所以temp1
被设置为temp1->next->next
哪个是NULL
,temp2
被设置为temp2->next
哪个是value=3
节点。 -
在第三次循环迭代中,
temp1
NULL
因此访问temp1->next
是未定义的行为,并且代码失败。
因此,要解决此问题,您需要将循环更改为更像这样的东西:
void mid_list(Node* head)
{
if (head == NULL) return;
Node* temp1 = head;
Node* temp2 = head;
while (temp1->next != NULL) {
temp1 = temp1->next->next;
if (temp1 == NULL) break;
temp2 = temp2->next;
}
cout << temp2->value;
}
现场演示
或:
void mid_list(Node* head)
{
if (head == NULL) return;
Node* temp1 = head;
Node* temp2 = head;
while ((temp1 != NULL) && (temp1->next != NULL)) {
temp1 = temp1->next->next;
temp2 = temp2->next;
}
cout << temp2->value;
}
现场演示
根据您在迭代偶数大小列表时实际感兴趣的"中间"节点 - 中点左侧或右侧的节点。
你的代码中有一个错误,在 while 条件下,你必须检查"temp1->next",因为你在循环中指向它的下一个,如果 temp->next 是 NULL,那么 temp1->next->next 将是未定义的。下面的代码可以正常工作:
void mid_list(Node* head) {
Node* temp1 = head;
Node* temp2 = head;
while (temp1!=NULL && temp1->next != NULL) { // here I have modified this line.
temp1 = temp1->next->next;
temp2 = temp2->next;
}
cout << temp2->value;
}
如果我理解正确,您正在寻找中间节点。下一个片段可以解决问题:
void mid_list(Node* head)
{
Node* temp1 = head;
auto nodeCount = 0u;
while (temp1->next != nullptr) // walk through nodes if exists
{
temp1 = temp1->next;
++nodeCount; //count valid nodes
}
temp1 = head; //reset the temp
for (auto ii=0u; nodeCount / 2 > ii; ++ii ) // walk to the middle node from the head
{
temp1 = temp1->next;
}
if (nullptr != temp1) // sanity check
std::cout << temp1->value;
}
对于奇数个条目,它是一个真正的中间,因为即使它是前面的节点(如果你从 0 开始计数(或紧随"中间"索引之后的节点(如果从 1 开始(。
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 2D数组来自文本输入,中间有空格
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 链表错误的中间
- 使用C++未来值作为函数堆栈中的中间值会导致段错误
- 我的代码停在中间,没有错误C
- 如何在列表中间释放删除的节点,而没有阀门错误
- 致命错误 C1083:无法打开编译器中间文件:"***.pch":没有此类文件或目录
- c++计算器atof没有错误,但它在中间一行崩溃(52)
- C++:printf中间的分段错误,但仅适用于Ubuntu