【问题标题】:Why does reordering of linked list fail?为什么链表重新排序失败?
【发布时间】:2020-01-13 06:51:16
【问题描述】:

在此代码中,我尝试使用 evenOdd() 函数修改列表,使偶数出现在列表中的第一位,奇数出现在列表中的最后。
但是没有得到预期的输出,请帮帮我。

预期输出:

订购前:
1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> NULL
订购后:
2 --> 4 --> 6 --> 1 --> 3 --> 5 --> 7 --> NULL

实际输出:

1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> NULL

#include<iostream>
using namespace std;

class Node
{
public:
    int data;
    Node* next;
};

void addEnd(Node **head, int val)
{
    Node *temp=*head;
    Node *newnode=new Node();
    newnode->data=val;
    newnode->next=NULL;
    if(*head == NULL) {*head = newnode; return;}
    while(temp->next!=NULL) {temp=temp->next;}
    temp->next=newnode;
}

void deleteKey(Node **head,int val)
{
    Node *temp=*head;
    Node* prev;
    if(temp!=NULL and temp->data == val)
    {
        *head = temp->next;
        delete temp;
        return;
    }
    while(temp->next!=NULL)
    {
        if(temp->data == val) {prev = temp; break;}
        prev=temp;
        temp=temp->next;
    }
    if(temp->data != val) {cout<<"NO SUCH VAlUES"; return;}
    prev->next=temp->next;
}

void evenOdd(Node **head)
{
    Node *temp = *head;
    while(temp != NULL)
    {
        if(temp->data%2 == 1)
        {addEnd(*(&head),temp->data); deleteKey(*(&head),temp->data);}
        temp = temp->next;
    }
}

void printList(Node *node)
{
    while(node!=NULL)
    {
        cout<<"  "<<node->data<<" --> ";
        node=node->next;
    }
    cout<<"NULL";
}

int main()
{
    Node *head = NULL;
    addEnd(&head,1);
    addEnd(&head,2);
    addEnd(&head,3);
    addEnd(&head,4);
    addEnd(&head,5);
    addEnd(&head,6);
    addEnd(&head,7);
    cout<<"Before Ordering :\n";
    printList(head);
    evenOdd(&head);
    cout<<"After Ordering :\n";
    printList(head);
    return 0;
}

【问题讨论】:

    标签: c++ data-structures singly-linked-list


    【解决方案1】:

    有了这个组合

    if(temp->data%2 == 1)
    

    deleteKey(*(&head),temp->data);
    

    您正在删除当前正在查看的节点。包括一个实际的

    delete temp;
    

    deleteKey.

    然后你访问你刚刚删除的内存,这里

    temp = temp->next;
    

    evenOdd内。

    在那之后,所有的赌注都取消了。

    但是观察到的问题是在deleteKey内部引起的:

    prev->next=temp->next; 
    

    它使用prev,其值与temp相同。
    IE。它不会改变温度,尤其是指向温度的指针。
    为此,您需要跟踪指向要删除的节点的指针,并更改 THAT。
    你的变量的命名说明你知道这个概念并尝试在这里做

    {prev = temp; break;}
    

    但显然无法检索指针。
    您需要一直更新 prev,然后在您的删除代码中添加类似的内容

    {prev->next = temp->next; break;} /* prev->next currently points to temp, but prev!= temp */
    /* update the "next" pointing to current node so that it points to the next one */
    

    您可能会发现我的其他答案对于分析此类 poitner 问题很有用:
    Tricks to analyse pointer and pointer-to-pointer structures in C?

    【讨论】:

    • 或者使用节点linked list delete的地址大大简化删除。这消除了完全跟踪prev 指针的需要。
    【解决方案2】:

    在 evenOdd 函数中temp 指向插入在后面的节点,而根据迭代它应该指向第 2、3、4 个节点。所以当你做 temp = temp->next 时,它会溢出。

    【讨论】:

    • 如何?,我只是将temp的数据添加到列表的后面,temp变成temp -> next。即 temp 只到 2,3,4 rd 节点,而不是新添加的节点,对吧?
    猜你喜欢
    • 1970-01-01
    • 2015-04-04
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多