链表错误的中间
Middle of a linked list bug
我写了一个函数来打印单链表的中间部分,但是当列表长度为奇数时,它不打印它(不打印任何东西只是空白 space),当列表length是偶数,打印的是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;
}
如果我没理解错的话,你是在找中间节点。下一个片段可以解决问题:
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 开始)。
让我们逐步了解您的奇数列表示例的逻辑:
进入mid_list()
后,head
为value=1
节点,temp1
和temp2
设置为head
。请注意,您没有为 NULL
检查 head
,因此如果列表为空,您的代码将失败,但在本示例中并非如此。
在第一次循环迭代中,temp1->next
不是 NULL
,因此 temp1
设置为 temp1->next->next
,即 value=3
节点,temp2
设置为 temp2->next
,即 value=2
节点。
在第 2 次循环迭代中,temp1->next
是 NULL
,因此循环中断,并打印 value=2
节点(不是空白 space,就像你声称的那样)。到目前为止,还不错。
现在,让我们逐步了解偶数列表的逻辑:
进入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
节点。
在第 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- >接下来是 undefined.The 下面的代码可以正常工作:
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;
}
我写了一个函数来打印单链表的中间部分,但是当列表长度为奇数时,它不打印它(不打印任何东西只是空白 space),当列表length是偶数,打印的是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;
}
如果我没理解错的话,你是在找中间节点。下一个片段可以解决问题:
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 开始)。
让我们逐步了解您的奇数列表示例的逻辑:
进入
mid_list()
后,head
为value=1
节点,temp1
和temp2
设置为head
。请注意,您没有为NULL
检查head
,因此如果列表为空,您的代码将失败,但在本示例中并非如此。在第一次循环迭代中,
temp1->next
不是NULL
,因此temp1
设置为temp1->next->next
,即value=3
节点,temp2
设置为temp2->next
,即value=2
节点。在第 2 次循环迭代中,
temp1->next
是NULL
,因此循环中断,并打印value=2
节点(不是空白 space,就像你声称的那样)。到目前为止,还不错。
现在,让我们逐步了解偶数列表的逻辑:
进入
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
节点。在第 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- >接下来是 undefined.The 下面的代码可以正常工作:
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;
}