weixin_39965936 2021-10-20 18:36 采纳率: 68.8%
浏览 20

为什么在销毁链表的函数中delete之后,L最后的next就从头结点变成了野指针呢?

题目要求:
int Delete(Linklist, int , ElemType&)//删除Linklist中int位置的节点,节点data值用第三个参数带回。函数返回值为成功,不成功:1,-1

int length(LinkList) //求链表长度,返回长度

int LocateElem(LinkList, ElemType, int&)//给定某ElemType元素,查找其在Linklist中的节点序号,节点序号用第三个参数带回。函数返回值为成功,不成功:1,-1

void Destory(LinkList&)//销毁单链表

主函数中:

创建一个单链表L:1,2,3,4,5,6。遍历并打印链表长度。

删除编号1的节点,打印删除节点的data,遍历并链表长度。

删除编号5的节点,打印删除节点的data,遍历并链表长度。

查找数据7,如果成功打印节点编号,不成功打印“没有该节点”

查找数据3,如果成功打印节点编号,不成功打印“没有该节点”

销毁L。

创建L:6,7,8,9,0。遍历,打印链表长度。

销毁L。

#include <iostream>
#include "stdio.h"
#include "stdlib.h"
using namespace std;
typedef int Elemtype;
typedef struct LNode {
    Elemtype data;
    struct LNode* next;
}LNode, * Linklist;
Linklist L;
//初始化
void InitList(Linklist& L);
void Travel(Linklist& L);
void CreateList_H(Linklist& L, int n);
void CreateList_R(Linklist& L, int n);
int ListInsert(Linklist& L, int i);
int GetElem(Linklist& L, int i);
int Delete(Linklist L, int i, int& e);
int length(Linklist);
int LocateElem(Linklist L, int e, int& i);
void destroyList(Linklist& L);
//函数声明
void InitList(Linklist& L) {
    L = new LNode;
    L->next = L;
}
void Travel(Linklist& L) {
    LNode* p;
    p = L->next;
    while (p != L) {
        printf("%d ", p->data);
        p = p->next;
    }
    //free(p);
}
void CreateList_H(Linklist& L, int n) {
    int i = 0; LNode* p;
    printf("请输入%d个元素", n);
    for (i = 0; i < n; i++) {
        p = new LNode;
        cin >> p->data;
        p->next = L->next;
        L->next = p;
    }
}
void CreateList_R(Linklist& L, int n) {
    int i = 0; LNode* r, * p;
    r = L;//为什么等于L?因为此时是插入,只有头结点,没有首元节点
    printf("请输入%d个元素", n);
    for (i = 0; i < n; i++) {
        p = new LNode;
        cin >> p->data;
        p->next = L;
        r->next = p;
        r = p;
    }
}int ListInsert(Linklist& L, int i) {
    int j = 0; LNode* p, * s;
    p = L; j = 0;//为什么?因为从头结点开始
    while (p->next!=L && (j < i - 1)) {
        p = p->next;//遍历
        j++;
    }
    if (j > i - 1) //判断i值是否合法
        return 0;
    if (p->next == L && (j < i - 1)) {
        s= new LNode;
        printf("请输入要插入的值");
        cin >> s->data;
        s->next = p->next;
        p->next = s;
        printf("%d已经插入到了%d位置", s->data, i);
    }
    else {
        s = new LNode;
        printf("请输入要插入的值");
        cin >> s->data;
        s->next = p->next;
        p->next = s;
        printf("%d已经插入到了%d位置", s->data, i);
    }
}
int GetElem(Linklist& L, int i) {
    LNode* p; int j = 1;
    Elemtype e = 0;
    p = L->next;
    while (p!=L && j < i)
    {
        p = p->next;
        j++;
    }
    if (!p || j > i)
        return 0;
    e = p->data;
    printf("编号为%d的结点为%d", i, e);
}
int Delete(Linklist L, int i, int& e) {
    LNode* p = L->next;
    int j = 0;
    while ((p->next->next!=L)&& (j < i - 1)) {
        p = p->next;
        j++;
    }
    if (j > i - 1) return -1;
    if (j==0) {
        e = p->data;
        L->next = p->next;

        return 1;
    }
    LNode* q;
    q = p->next;
    /*if (q == L) {
        e =( q->next)->data;
        p->next = q->next->next;
        return 2;
    }
    else {*/
        e = q->data;
        p->next = q->next;
    // }
    //free(q);
    return 3;
}//删除
int length(Linklist L) {
    LNode* p = L->next;
    int cnt = 0;
    while (p != L) {
        p = p->next;
        cnt++;
    }
    //free(p);
    return cnt;
}
int LocateElem(Linklist L, int e, int& i) {
    int data = 1;
    LNode* p;
    p = L->next;
    while (p!=L && p->data != e) {
        p = p->next;
        data++;
        i = data;
    }
    if (p==L) return -1;
    return 1;
}

//销毁链表
void destroyList(Linklist& L) {
    LNode* p = L;
    while (p->next!=L)
    {
        L = L->next;
        //        free(p);
        delete(p);
        p = L;
    }
}

#include "CirLinkList.h"
int main() {
    Linklist L;
    int i, e = 0;
    InitList(L);
    CreateList_R(L, 6); 
    Travel(L); printf("\n"); printf("长度为%d", length(L)); printf("\n");
    Delete(L, 1, e); printf("已完成删除操作,删除结点的值为%d\n", e); Travel(L);  printf("长度为%d", length(L)); printf("\n");
    Delete(L, 5, e); printf("已完成删除操作,删除结点的值为%d\n", e); 
    Travel(L);  printf("长度为%d", length(L)); printf("\n");
    if (LocateElem(L, 7, i) == 1) {
        printf("7的位置在%d\n ", i);
    }
    else { printf("没有该结点"); }
    if (LocateElem(L, 3, i) == 1) {
        printf("3的位置在%d\n", i);
    }
    else { printf("没有该结点\n"); }
    destroyList(L); printf("已销毁");
    //Linklist L;
    InitList(L);
    CreateList_R(L, 5);
    Travel(L);
    printf("链表长度为%d\n", length(L));
    destroyList(L); printf("已销毁");
}

  • 写回答

1条回答 默认 最新

  • 赵4老师 2021-10-20 18:40
    关注

    因为参数是引用

    评论

报告相同问题?

问题事件

  • 创建了问题 10月20日

悬赏问题

  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?