Gilgamesh_02 2023-01-02 15:38 采纳率: 50%
浏览 31
已结题

遍历链表时分发现链表尾的next指向尾本身

在合并两个升序链表时,当p2指针到达最后一个元素时,直接令p->next = p2,但我理解p2->next本身是NULL,那么p后面连接上p2以后,p->next->next不应该是NULL了吗?
但事实是p->next->next指向它本身导致无限循环。

以下为C++代码:

#include <iostream>

using namespace std;


//Definition for singly-linked list.
 struct ListNode {
     int val;
      ListNode *next;
      ListNode() : val(0), next(nullptr) {}
      ListNode(int x) : val(x), next(nullptr) {}
      ListNode(int x, ListNode *next) : val(x), next(next) {}
};
 
 //将两个升序链表合并为一个新的 升序 链表并返回。
 //新链表是通过拼接给定的两个链表的所有节点组成的。
 ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
     
     //当你需要创造一条新链表的时候,可以使用虚拟头结点简化边界情况的处理。
     ListNode *dummy = new ListNode(-1), *p = dummy;

     ListNode *p1 = list1, *p2 = list2;

     while ((p1 != NULL) && (p2 != NULL))
     {
         if (p1->val <= p2->val)
         {
             p->next = p1;
             p1 = p1->next;
         }
         else
         {
             p->next = p2;
             p2 = p2->next;
         }
         p = p->next;
     }

     if (p1 != NULL)
     {
         p->next = p1;
     }

     if (p2 != NULL)
     {
         p->next = p2;
     }

     return dummy->next;

 }

 int main()
 {
     ListNode  a3(4);
     ListNode  b3(4);
     ListNode a2(2, &a3), l1(1, &a2);
     ListNode b2(3, &a3), l2(1, &b2);

     for (ListNode* p = &l1; p != NULL; p = p->next)
     {
         cout << p->val << " ";
     }

     cout << endl;
     
     for (ListNode* p = &l2; p != NULL; p = p->next)
     {
         cout << p->val << " ";
     }

     cout << endl;

     ListNode* lp = mergeTwoLists(&l1, &l2);
    
     for (ListNode* p = lp; p != NULL; p = p->next)
     {
         cout << p->val << " ";
     }

     
     return 0;
 }

期望结果为112344,运行结果为链表最后一个4无限循环。

img


可以看到在执行p->next = p2之前,p->是NULL;

img


但执行p->next = p2后,p->指向了p本身。

我的想法是在链表最后插入一个NULL,我认为是p->next->next = NULL;但结果为11234,链表少一个元素。
请指点为什么p->next会指向p本身,以及应该如何改动。

  • 写回答

2条回答 默认 最新

  • 真相重于对错 2023-01-02 18:08
    关注

    你的代码太混乱了,你给的两个链表,最后一个元素是同一个,当你合并的时候采用从原先两个链表移动到新链表下,必然会出现错误。
    建议不用移动节点而是复制节点。

    #include <iostream>
    
    using namespace std;
    
    
    //Definition for singly-linked list.
    struct ListNode {
        int val;
        ListNode* next;
        ListNode() : val(0), next(nullptr) {}
        ListNode(int x) : val(x), next(nullptr) {}
        ListNode(int x, ListNode* next) : val(x), next(next) {}
    };
    
    //将两个升序链表合并为一个新的 升序 链表并返回。
    //新链表是通过拼接给定的两个链表的所有节点组成的。
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
    
        //当你需要创造一条新链表的时候,可以使用虚拟头结点简化边界情况的处理。
        ListNode* dummy = new ListNode(-1), * p = dummy;
    
        ListNode* p1 = list1, * p2 = list2;
    
        while ((p1 != NULL) && (p2 != NULL))
        {
            ListNode* tmp = new ListNode();
            if (p1->val <= p2->val)
            {
                tmp->val = p1->val;
                p1 = p1->next;
            }
            else
            {
                tmp->val = p2->val;
                p2 = p2->next;
            }
            p->next = tmp;
            p = tmp;
        }
    
        if (p1 != NULL)
        {
            while (p1 != nullptr) {
                ListNode* tmp = new ListNode(p1->val);
                p1 = p1->next;
                p->next = tmp;
                p = tmp;
            }
        }
    
        if (p2 != NULL)
        {
            while (p2 != nullptr) {
    
                ListNode* tmp = new ListNode(p2->val);
                p2 = p2->next;
                p->next = tmp;
                p = tmp;
            }
        }
    
        return dummy->next;
    
    }
    
    int main()
    {
        ListNode  a3(4);
        ListNode  b3(4);
        ListNode a2(2, &a3), l1(1, &a2);
        ListNode b2(3, &a3), l2(1, &b2);
    
        for (ListNode* p = &l1; p != NULL; p = p->next)
        {
            cout << p->val << " ";
        }
    
        cout << endl;
    
        for (ListNode* p = &l2; p != NULL; p = p->next)
        {
            cout << p->val << " ";
        }
    
        cout << endl;
    
        ListNode* lp = mergeTwoLists(&l1, &l2);
    
        for (ListNode* p = lp; p != NULL; p = p->next)
        {
            cout << p->val << " ";
        }
    
    
        return 0;
    }
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 1月10日
  • 已采纳回答 1月2日
  • 创建了问题 1月2日

悬赏问题

  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题
  • ¥20 yolov5自定义Prune报错,如何解决?