飒泽 2021-10-07 18:59 采纳率: 100%
浏览 46
已结题

双向链表删除指定元素算法中无法正常返回删除的数据



```c
int DeleteElem(DuLinkList L, int target, Stu * s){
    DuLNode * p = L->next;
    int index = 1;
    while(p->next && index<target){
        p = p->next;
        index++;
    }
    if(target<1 || index<target){
        printf("指定位置不存在\n");
        return -1;
    }
    if(!(p->next)){  // 要删除元素在尾部的情况
        *s = p->s;
        p->prior->next = p->next;
        printf("尾部删除成功\n");
        return 1;
    }

    // 要删除的元素在头部或中间的情况;
    *s = p->s;

    p->next->prior = p->prior;
    p->prior->next = p->next;
    printf("删除成功\n");
    return 1;
}

void main1(){
      Stu *s = NULL;
      DeleteElem(L, 1, s);
      printf("姓名:%s,序号:%d",s->name, s->num);
}

void main2(){
      Stu s;
      DeleteElem(L, 1, &s);
      printf("姓名:%s,序号:%d",s.name, s.num);
}

DeleteElem函数的作用是删除指定位置的元素,被删除的数据通过传入的 s 返回
main1()中程序正常执行到DeleteElem();之后命令行窗口中就会光标闪几下然后自动关闭(是在赋值那步就出现问题而不是在打印的那步)
而main2()中给DeleteElem传入一个地址值而不是指针就可以正常执行
我想问一下为什么main1()中的传值方法不能成功给s赋值
还有哪些错误会导致命令行窗口自动关闭,感觉经常会遇到这样的情况。

上面只是摘录了有问题的那段代码
后面附上整个代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct Stu{
    char * name;
    int num;
}Stu;
typedef struct DuLNode{
    Stu s;
    DuLNode  *prior,*next; 
}DuLNode,*DuLinkList;

int InitList(DuLinkList & L){
    L = (DuLinkList)malloc(sizeof(DuLNode));
    if(!L){
        printf("创建失败\n");
        return -1;
    }
    L->s.name = "我是头结点哦";
    L->prior = NULL;
    L->next = NULL;
    return 1;
}

int InsertElem(DuLinkList L, int target, Stu s){
    int index = 0;
    DuLNode *p = L;
    if(target == 1){       // 如果插入在首位需要单独考虑
        DuLNode * ND = (DuLinkList)malloc(sizeof(DuLNode));
        ND->s = s;   // 创建好要插入的结点

        ND->prior = p;
        ND->next = p->next;
        p->next = ND;
        printf("头部插入成功\n");
        return 1;
    }

    while(p->next && index<target){
        p = p->next;
        index++;
    }
    if(target<1 || index < target-1){    // 如果要插入的位置小于1或者大于链表总长度+1,位置非法
        printf("指定位置不存在\n");
        return -1;
    }

    if(!(p->next) && index==target-1){    // 判断要插入的位置是不是尾部,尾部插入也需要特殊考虑
        DuLNode * ND = (DuLNode*)malloc(sizeof(DuLNode));
        ND->s = s;
        p->next = ND;
        ND->prior = p;
        ND->next = NULL;
        printf("尾部插入成功\n");
        return 1;
    }

    // 下面就是插入位置在中间的情况 

    DuLNode* ND = (DuLinkList)malloc(sizeof(DuLNode));
    ND->s = s;

    ND->prior = p->prior;    // 添加结点的核心操作
    ND->next = p;
    p->prior->next = ND;
    p->prior = ND;
    
    printf("中间插入成功\n");
    return 1;
}

// 删除指定位置的元素,通过传入的参数s返回,只有删除尾元素需要单独考虑
int DeleteElem(DuLinkList L, int target, Stu * s){
    DuLNode * p = L->next;
    int index = 1;
    while(p->next && index<target){
        p = p->next;
        index++;
    }
    if(target<1 || index<target){
        printf("指定位置不存在\n");
        return -1;
    }
    if(!(p->next)){  // 要删除元素在尾部的情况
        *s = p->s;
        p->prior->next = p->next;
        printf("尾部删除成功\n");
        return 1;
    }

    // 要删除的元素在头部或中间的情况;
    *s = p->s;

    p->next->prior = p->prior;
    p->prior->next = p->next;
    printf("删除成功\n");
    return 1;
}

void PrintList(DuLinkList L){
    DuLNode * p = L;
    while(p->next){
        p = p->next;
        printf("姓名:%s,序号:%d\n",p->s.name,p->s.num);
    }
}

void main(){
    DuLinkList L = NULL;
    InitList(L);
    printf("%s\n",L->s.name);
    Stu s1,s2,s3,s4,*s = NULL;
    s1.name = "A";
    s1.num = 1;
    s2.name = "B";
    s2.num = 2;
    s3.name = "C";
    s3.num = 3;
    s4.name = "D";
    s4.num = 4;

    InsertElem(L,1,s1);
    InsertElem(L,2,s2);
    InsertElem(L,2,s3);
    InsertElem(L,1,s4);
    PrintList(L);
    printf("%s",L->next->prior->s.name);
    DeleteElem(L,1,s);
    PrintList(L);

    printf("删掉的元素 姓名:%s,序号:%d",s->name,s->num);

    system("pause");
}

  • 写回答

2条回答 默认 最新

  • CSDN专家-link 2021-10-07 19:04
    关注

    main1肯定不行啊。s是个指针,没有分配空间,你就进行*s=p->s的赋值操作,肯定崩溃了啊

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

报告相同问题?

问题事件

  • 系统已结题 10月15日
  • 已采纳回答 10月7日
  • 修改了问题 10月7日
  • 创建了问题 10月7日

悬赏问题

  • ¥50 我在一个购物网站的排队系统排队,这个排队到号后重新定向到目标网站进行购物,但是有技术牛通过技术方法直接跳过排队系统进入目标网址购物,有没有什么软件或者脚本可以用
  • ¥15 ios可以实现ymodem-1k协议 1024字节传输吗?
  • ¥300 寻抓云闪付tn组成网页付款链接
  • ¥15 请问Ubuntu要怎么安装chrome呀?
  • ¥15 视频编码 十六进制问题
  • ¥15 unity terrain打包后地形错位,跟建筑不在同一个位置,怎么办
  • ¥15 FileNotFoundError 解决方案
  • ¥15 uniapp实现如下图的图表功能
  • ¥15 u-subsection如何修改相邻两个节点样式
  • ¥30 vs2010开发 WFP(windows filtering platform)