水上由岐~ 2024-06-18 00:15 采纳率: 76.9%
浏览 0
已结题

为什么L2赋值给l2结果显示l2为nullper??


#include<stdio.h>
#include<iostream>
using namespace std;
// 定义链表节点结构
typedef struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
} Node;
//采用头插法建立双链表
void  createlistf(Node*& l, int s[], int n) {
    int no = n - 1;//由于是头插法,若no从0开始则编号为倒序,故从n-1开始递减
    Node* head;
    l = (Node*)malloc(sizeof(Node));
    l->prev = l->next = NULL; 
    for (int i = 0; i < n; i++) {
        head = (Node*)malloc(sizeof(Node));
        head->data = s[i];//给data赋值
        head->next = l->next;//使head结点的下一节点为头结点l的下一节点
        if (l->next != NULL)//若头结点的下一节点不为空
            l->next->prev = head;//则让其prev指针指向head
        head->prev = l;//令head的prev指针指向头结点
        l->next = head;//最后再改变l的next指针指向,让其指向head
    }
}
void printList(Node* head) {
    Node* temp = head->next;//指向首结点
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}
// 冒泡排序函数(最后从小到大排序)
void bubblesort(Node*& l) {
    int lnum, rnum;//左端点序号和右端点序号
    lnum = 0;
    Node* l0 = l;
    int no = -1;
    while (l0->next != NULL) {
        l0 = l0->next; no++;
    }//遍历双链表直到最后一个节点
    rnum = no;//得到最右端序号
    int n = rnum + 1;//记录下双链表长度
    Node* L1 = l->next;//L1为双链表首结点
    Node* L2 = l0;//L2为双链表尾结点
    cout << l0->data;
    while (lnum <= rnum)//该循环的终止条件为左端点序号超过右端点序号
    {
        Node* l1=L1; //每次循环都建立l1,l2储存L1,L2的位置
        while (l1->next != L2->next)//l1从前往后遍历,直到来到L2结点
        {
            int temp;
            if (l1->data > l1->next->data)
            {
                temp = l1->data;
                l1->data = l1->next->data;
                l1->next->data = temp;
            }//交换
            l1 = l1->next;//前往后一节点
        }printList(l);
        L2 = L2->prev;
        Node* l2 = L2;
        while (l2->prev != L1->prev)//l2从后往前遍历,直到来到L1结点
        {
            int temp;
            if (l2->data < l2->prev->data) {
                temp = l2->data;
                l2->data = l2->prev->data;
                l2->prev->data = temp;
            }
            //交换
            l2 = l2->next;//前往前一节点
        }lnum++; rnum++;
        L1 = L1->next;
       
    }
}

int main() {
    Node* head = NULL;
    int a[] = { 12,25,15,35,675,1,9,6 };
    createlistf(head, a, 8);
   
    printf("Original list:\n");
    printList(head);
    bubblesort(head);
    printList(head);

}

为什么L2赋值给l2结果显示l2为nullper??

img

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-18 00:16
    关注

    引自免费微信小程序:皆我百晓生

    在你提供的代码中,L2 被初始化为链表的最后一个节点,而 l2 是在冒泡排序的过程中被赋值为 L2 的副本。当 l2 在从后向前遍历的过程中试图访问 l2->prev 时,它遇到了 nullptr 并引发了异常,这表明在某个时刻 l2 指向了一个不存在的节点。

    问题的根本在于 l2 在遍历过程中没有正确地更新。在遍历过程中,L2 的值在不断改变(通过 L2 = L2->prev;),但 l2 的值却没有随之更新,导致了 l2 指向了一个不再有效的地址。

    为了修复这个问题,你需要确保 l2 总是指向当前的 L2。这可以通过在每次循环开始时重新初始化 l2 来实现,即:

    while (l2->prev != L1->prev){
        //...
    }
    

    应改为:

    Node* l2 = L2;
    while (l2->prev != L1->prev){
        //...
    }
    

    这样,在每次循环开始时,l2 都会被设置为最新的 L2 值,从而避免了指向一个已经移动或释放的节点。

    以下是修改后的冒泡排序函数部分:

    void bubblesort(Node*& l) {
        int lnum, rnum;
        lnum = 0;
        Node* l0 = l;
        int no = -1;
        while (l0->next != NULL) {
            l0 = l0->next; no++;
        }
        rnum = no;
        int n = rnum + 1;
        Node* L1 = l->next;
        Node* L2 = l0;
    
        while (lnum <= rnum) {
            Node* l1 = L1;
            while (l1->next != L2->next) {
                int temp;
                if (l1->data > l1->next->data) {
                    temp = l1->data;
                    l1->data = l1->next->data;
                    l1->next->data = temp;
                }
                l1 = l1->next;
            }
            L2 = L2->prev;
            // 修改这里:重新初始化 l2
            Node* l2 = L2;
            while (l2->prev != L1->prev) {
                int temp;
                if (l2->data < l2->prev->data) {
                    temp = l2->data;
                    l2->data = l2->prev->data;
                    l2->prev->data = temp;
                }
                l2 = l2->next;
            }
            lnum++; rnum--;
            L1 = L1->next;
        }
    }
    

    这样修改后,l2 应该能够正确地遍历并参与排序过程,不会再次引发 nullptr 异常。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月29日
  • 已采纳回答 6月21日
  • 创建了问题 6月18日

悬赏问题

  • ¥30 模拟电路 logisim
  • ¥15 PVE8.2.7无法成功使用a5000的vGPU,什么原因
  • ¥15 is not in the mmseg::model registry。报错,模型注册表找不到自定义模块。
  • ¥15 安装quartus II18.1时弹出此error,怎么解决?
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音
  • ¥30 Pytorch深度学习服务器跑不通问题解决?
  • ¥15 部分客户订单定位有误的问题
  • ¥15 如何在maya程序中利用python编写领子和褶裥的模型的方法
  • ¥15 Bug traq 数据包 大概什么价