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

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

以下为C++代码:

#include 

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本身,以及应该如何改动。

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

#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;
}