豆葛 2022-04-30 15:08 采纳率: 50%
浏览 34
已结题

C语言,链表删除特定结点时遇到了问题;还有将列表逆转,运用迭代法来逆转函数时,函数也出现了问题

问题遇到的现象和发生背景
#include <stdio.h>
#include <stdlib.h>

struct B  //头尾结点指针
{
    struct A *head,*tail;
}C;
typedef struct A  //链表结点的结构体
{
    int number;
    struct A* next;

}single_list;
int creat()  //创建链表函数,没有问题
{   int n=0;
    single_list *next;
    printf("请输入数据:\n");
    int c=1;
    printf("please input l(*^o^*)L:");
    c=scanf("%d",&n);
    getchar();
    if(c==0)
    {
        printf("\n l(QAQ)l:主人您未创建任何链表数据\n");
        C.head=NULL;
        C.tail=NULL;
        return 1;
    }
    else
    {
        C.head=(single_list*)malloc(sizeof(single_list));
        C.head->number=n;
        C.head->next=NULL;
        C.tail=C.head;
        c=1;
        printf("continue_L(*^O^*)L:");
        c=scanf("%d",&n);
        getchar();
        if(c==0) {
            printf("您成功创建了有一个数据的链表!");
            return 1;
        }
        while(1)
        {
            next=(single_list*)malloc(sizeof(single_list));
            next->number=n;
            next->next=NULL;
            C.tail->next=next;
            C.tail=next;
            printf("continue_L(*^O^*)L:");
            c=1;
            c=scanf("%d",&n);
            getchar();
            if(c==0) {
                printf("\n您创建链表成功啦!\n");
                return 1;
            }
        }
    }

}

int print_link(single_list *head,int i) //问题出在case 3
{
    int flags=0,u=0,u1=0,u2=0;
    single_list *flag,*next;
    flag=head;
    switch (i)
    {

//        case 1:
//            printf("请输入你要添加的值(int):");
//            while (scanf("%d", &flags) != 1)   //限制用户只能输入整数类型
//            {
//                getchar();
//                printf("输入内容非法,请重新输入!\n 重新输入的内容是:");
//            }
//            next=(single_list*)malloc(sizeof(single_list));
//            next->number=flags;
//            next->next=NULL;
//            if(C.head==NULL)
//            {
//                C.head=next;
//                C.tail=next;
//            }
//            else
//            {
//                C.tail->next = next;
//                C.tail = next;
//                printf("成功添加!");
//            }
//            break;
//        case 2:
//            //读取指定位置并且在指定位置添加输入的值
//            printf("please input the where to add value:\n");
//            u=print_link(C.head, 9);  //读取链表长度并记录
//            while (scanf("%d", &flags) != 1 )
//            {
//                getchar();
//                printf("输入内容非法,请重新输入!\n 重新输入的内容是:");
//            }
//            printf("\n请输入您要添加的值:");
//            while (scanf("%d", &u1) != 1)   //限制用户只能输入整数类型
//            {
//                getchar();
//                printf("输入内容非法,请重新输入!\n 重新输入的内容是:");
//            }
//            if(flags==1 )
//            {
//                printf("执行插入头指针");
//                next=(single_list*)malloc(sizeof(single_list));
//                next->number=u1;
//                next->next=head;
//                C.head=next;
//                if(u==0)
//                    C.tail=next;
//                return 1;
//            }
//            else if(flags>=u+1)
//            {
//                next=(single_list*)malloc(sizeof(single_list));
//                next->number=u1;
//                next->next=NULL;
//                C.tail->next=next;
//                C.tail=next;
//                if(u==0)
//                    C.head=next;
//
//                return 1;
//            }
//            else
//            {
//
//                u2=1;
//                while(u2!=flags) //1!=3  2 1-2, 2!=3  3 2-3 3找到要插入的前一个指针
//                {
//                    u2++; //2
//                    flag=flag->next;//1-2 2-3
//                }
//                next=(single_list*)malloc(sizeof(single_list));
//                next->number=u1;
//                next->next=flag->next;
//                flag->next=next;
//                return 1;
//            }
        case 3:  //删除对应的链表
            printf("please input the where to delete value:\n");
            u=print_link(C.head, 9);  //读取链表长度并记录
            if(u==0)  //如果链表长度为零,返回信息
            {
                printf("no value can delete\n");
                return 0;
            }
            if(u==1)  //如果链表长度为1,那么返回信息,确认并删除
            {
                printf("only exist one value ,are you sure delete it?\nyes:1,no:default");

                scanf("%d",&u2);

                if(1==u2)
                {
                    free(C.head);
                    C.head=NULL;
                    C.tail=NULL;
                    return 1;
                }
            }
//如果非上边两个情况,那么就让用户输入要删除第几个位置的数据
        H:  while (scanf("%d", &flags) != 1 )  //让用户输入一个正整数
            {
                getchar();
                printf("输入内容非法,请重新输入!\n 重新输入的内容是:");
            }
            if(flags<=0)
            {
                printf("请输入正数!\n");
                goto H;
            }

            if(flags==1) //如果删除的是第一个,重新定位头指针,flag开头已经赋值为头指针
            {
                C.head=flag->next;
                free(flag);
            }
            else
            {//其他情况

                u1 = 2;
                while (u1 != flags) //2!=3  3 1-2, 2!=3  3 2-3 3找到要插入的前一个指针
                {
                    u1++; //2
                    flag = flag->next;//1-2 2-3
                }
                printf("flag的地址为:%d",flag);
                if(flags<u) //u为数组长度,flags为用户输入的要删除的第几个  //如果用户要删除的数据在头→尾之间,执行删除操作
                {           //同时,有问题的就是这段代码
                    printf("祸乱之源");
                    next=flag->next->next;
                    flag->next =next;//a ,b ,c  b
                    free(flag->next);
                    return 1;
                }  //在用户输入要删除的数字的位置大于等于尾结点的时候,删除尾结点,并且将尾指针重新赋值
                else
                {

                    free(flag->next);
                    flag->next=NULL;
                    C.tail=flag;
                    return 1;
                }

            }
            return 1;
//        case 4:
//            printf("请输入要修改链表的位置,从1开始:\n");
//            u=print_link(C.head, 9);  //读取链表长度并记录
//
//        PP:  while (scanf("%d", &flags) != 1 )
//            {
//                getchar();
//                printf("输入内容非法,请重新输入!\n 重新输入的内容是:");
//            }
//            if(flags<=0 && flags>u)
//            {
//                printf("请输入正确的数!\n");
//                print_link(C.head,9);
//                goto PP;
//            }
//            printf("\n请输入您要修改成的值:");
//            while (scanf("%d", &u1) != 1)   //限制用户只能输入整数类型
//            {
//                getchar();
//                printf("输入内容非法,请重新输入!\n 重新输入的内容是:");
//            }
//
//            u2=1;
//            while(u2!=flags) //1!=3  2 1-2, 2!=3  3 2-3 3找到要插入的前一个指针
//            {
//                u2++; //2
//                flag=flag->next;//1-2 2-3
//            }
//            flag->number=u1;
//            printf("修改完成!\n");
//            return 1;
//



        case 9:  //返回链表长度
            flags=0;
            while(flag!=NULL && ++flags)
            {
                flag=flag->next;
            }
            printf("这个链表有%d个数据\n",flags);
            return flags;
        default:
        {
            single_list *p;
            p = head;
            int z=0;
            printf("\nnumber           point        self_point\n");

            do
            {
                printf("%d:%d,%10d,%10d\n",++z,p->number,p->next,p);
                p=p->next;

            } while (p!=NULL);
        }
    }
    return 1;
}
//打印功能表
void operation()
{
    printf("\'1\'在末尾增加值  \'2\'指定位置增加值\n\'3\'删除指定值\'4\'修改固定位置的值\n\'5\'链表反转\'9\'输出链表长度\n\'11\'打印当前链表");
}

single_list * reverse(single_list *head) //递归逆转链表
{
    single_list  *last;
    if(head==NULL ||head->next==NULL)
    {
        return head;
    }
    last= reverse(head->next);
    head->next->next=head;
    head->next=NULL;
    C.tail=head;
    return last;


}
//迭代逆转链表,问题出现在else程序段
void diedai(single_list *head) {
    single_list *a, *b, *c;
    c = NULL;
    a = NULL;
    b = NULL;
    if (head == NULL || head->next == NULL);
    else {

        c = C.head->next->next;
        printf("c的地址为%d\t", c);
        a = C.head;
        printf("a的地址为%d\t", a);
        b = C.head->next;
        printf("b的地址为%d\t", b);
        a->next = NULL;
        printf("a指向的地址为%d\n\n", a->next);
        b->next = a;
        do {
            a = b;
            printf("a的地址为%d\t", a);
            b = c;
            printf("b的地址为%d\t", b);
            b->next = a;

            c = c->next;
            printf("c的地址为%d\n", c);

            C.head = b;
        } while (c != NULL);
    }
}

int reverseList(single_list *head)
{
    if (head == NULL)

    {  printf("你好");return 1;}
    single_list *cur, *pnext, *pre;//建立三个指针,当前指针,下一个指针,上一个指针
    cur = head;
    pre = NULL;
    while (cur) {
        pnext = pre->next;
        cur->next = pre;
        pre = cur;
        cur = pnext;
        printf("标记\n");
    }
    C.head=pre;
    return 1;

}



void main()
{
    int a = 1;
    printf("please creat a link:\n");
    creat();//创建link;
    operation();
    fflush(stdin);

    int llll = 0;
    while (a != 10)
    {
        fflush(stdin);
        printf("\n请输入对应数字执行对应操作\n");

//        if (llll++!=0)
//          operation();
        scanf("%d", &a);
        switch (a)
        {
            case 6:
                reverseList(C.head);
//                diedai(C.head);
                break;
            case 5:
            {
                C.head = reverse(C.head);
                break;
            }
            default:
            {

                if (a > 0 && a <= 11)
                    print_link(C.head, a);
                else
                    printf("error!\n");
            }
        }

    }
}


问题相关代码,请勿粘贴截图

//这段是关于删除固定结点的问题代码

 case 3:  //删除对应的链表
            printf("please input the where to delete value:\n");
            u=print_link(C.head, 9);  //读取链表长度并记录
            if(u==0)  //如果链表长度为零,返回信息
            {
                printf("no value can delete\n");
                return 0;
            }
            if(u==1)  //如果链表长度为1,那么返回信息,确认并删除
            {
                printf("only exist one value ,are you sure delete it?\nyes:1,no:default");

                scanf("%d",&u2);

                if(1==u2)
                {
                    free(C.head);
                    C.head=NULL;
                    C.tail=NULL;
                    return 1;
                }
            }
//如果非上边两个情况,那么就让用户输入要删除第几个位置的数据
        H:  while (scanf("%d", &flags) != 1 )  //让用户输入一个正整数
            {
                getchar();
                printf("输入内容非法,请重新输入!\n 重新输入的内容是:");
            }
            if(flags<=0)
            {
                printf("请输入正数!\n");
                goto H;
            }

            if(flags==1) //如果删除的是第一个,重新定位头指针,flag开头已经赋值为头指针
            {
                C.head=flag->next;
                free(flag);
            }
            else
            {//其他情况

                u1 = 2;
                while (u1 != flags) //2!=3  3 1-2, 2!=3  3 2-3 3找到要插入的前一个指针
                {
                    u1++; //2
                    flag = flag->next;//1-2 2-3
                }
                printf("flag的地址为:%d",flag);
                if(flags<u) //u为数组长度,flags为用户输入的要删除的第几个  //如果用户要删除的数据在头→尾之间,执行删除操作
                {           //同时,有问题的就是这段代码
                    printf("祸乱之源");
                    next=flag->next->next;
                    flag->next =next;//a ,b ,c  b
                    free(flag->next);
                    return 1;
                }  //在用户输入要删除的数字的位置大于等于尾结点的时候,删除尾结点,并且将尾指针重新赋值
                else
                {

                    free(flag->next);
                    flag->next=NULL;
                    C.tail=flag;
                    return 1;
                }

            }
            return 1;


void diedai(single_list *head) {
    single_list *a, *b, *c;
    c = NULL;
    a = NULL;
    b = NULL;
    if (head == NULL || head->next == NULL);
    else {

        c = C.head->next->next;
        printf("c的地址为%d\t", c);
        a = C.head;
        printf("a的地址为%d\t", a);
        b = C.head->next;
        printf("b的地址为%d\t", b);
        a->next = NULL;
        printf("a指向的地址为%d\n\n", a->next);
        b->next = a;
        do {
            a = b;
            printf("a的地址为%d\t", a);
            b = c;
            printf("b的地址为%d\t", b);
            b->next = a;

            c = c->next;
            printf("c的地址为%d\n", c);

            C.head = b;
        } while (c != NULL);
    }
}

上边这段是迭代逆转函数有关问题的相关代码

运行结果及报错内容

img

我的解答思路和尝试过的方法

尝试了很多方法,但是局限于知识面,不知道如何解决这个问题

我想要达到的结果

能够正常逆转函数和删除指定的结点

  • 写回答

3条回答 默认 最新

  • 关注

    代码写的有点乱
    (1)删除函数的问题,再最后面的if(flags<u)里,应该先fee(flag->next),然后再给flag->next赋值。
    (2)逆序的函数,你的迭代是啥意思?不就是递归吗,while循环和递归的方式都给你该了一下。
    修改后运行结果:

    img

    代码:

    
    #include <stdio.h>
    #include <stdlib.h>
    
    struct B  //头尾结点指针
    {
        struct A* head, * tail;
    }C;
    typedef struct A  //链表结点的结构体
    {
        int number;
        struct A* next;
    
    }single_list;
    int creat()  //创建链表函数,没有问题
    {
        int n = 0;
        single_list* next;
        printf("请输入数据:\n");
        int c = 1;
        printf("please input l(*^o^*)L:");
        c = scanf("%d", &n);
        getchar();
        if (c == 0)
        {
            printf("\n l(QAQ)l:主人您未创建任何链表数据\n");
            C.head = NULL;
            C.tail = NULL;
            return 1;
        }
        else
        {
            C.head = (single_list*)malloc(sizeof(single_list));
            C.head->number = n;
            C.head->next = NULL;
            C.tail = C.head;
            c = 1;
            printf("continue_L(*^O^*)L:");
            c = scanf("%d", &n);
            getchar();
            if (c == 0) {
                printf("您成功创建了有一个数据的链表!");
                return 1;
            }
            while (1)
            {
                next = (single_list*)malloc(sizeof(single_list));
                next->number = n;
                next->next = NULL;
                C.tail->next = next;
                C.tail = next;
                printf("continue_L(*^O^*)L:");
                c = 1;
                c = scanf("%d", &n);
                getchar();
                if (c == 0) {
                    printf("\n您创建链表成功啦!\n");
                    return 1;
                }
            }
        }
    
    }
    
    int print_link(single_list* head, int i) //问题出在case 3
    {
        int flags = 0, u = 0, u1 = 0, u2 = 0;
        single_list* flag, * next;
        flag = head;
        switch (i)
        {
        case 3:  //删除对应的链表
            printf("please input the where to delete value:\n");
            u = print_link(C.head, 9);  //读取链表长度并记录
            if (u == 0)  //如果链表长度为零,返回信息
            {
                printf("no value can delete\n");
                return 0;
            }
            if (u == 1)  //如果链表长度为1,那么返回信息,确认并删除
            {
                printf("only exist one value ,are you sure delete it?\nyes:1,no:default");
    
                scanf("%d", &u2);
    
                if (1 == u2)
                {
                    free(C.head);
                    C.head = NULL;
                    C.tail = NULL;
                    return 1;
                }
            }
            //如果非上边两个情况,那么就让用户输入要删除第几个位置的数据
        H:  while (scanf("%d", &flags) != 1)  //让用户输入一个正整数
        {
            getchar();
            printf("输入内容非法,请重新输入!\n 重新输入的内容是:");
        }
        if (flags <= 0)
        {
            printf("请输入正数!\n");
            goto H;
        }
        
        if (flags == 1) //如果删除的是第一个,重新定位头指针,flag开头已经赋值为头指针
        {
            C.head = flag->next;
            free(flag);
        }
        else
        {//其他情况
    
            u1 = 2;
            while (u1 != flags) //2!=3  3 1-2, 2!=3  3 2-3 3找到要插入的前一个指针
            {
                u1++; //2
                flag = flag->next;//1-2 2-3
            }
            printf("flag的地址为:%d", flag);
            if (flags < u) //u为数组长度,flags为用户输入的要删除的第几个  //如果用户要删除的数据在头→尾之间,执行删除操作
            {           //同时,有问题的就是这段代码
                printf("祸乱之源");
                next = flag->next->next;
    
                free(flag->next); //删除放在这里
    
                flag->next = next;//a ,b ,c  b
                
                return 1;
            }  //在用户输入要删除的数字的位置大于等于尾结点的时候,删除尾结点,并且将尾指针重新赋值
            else
            {
                free(flag->next);
                flag->next = NULL;
                C.tail = flag;
                return 1;
            }
           
    
        }
        return 1;
        
    
    
        case 9:  //返回链表长度
            flags = 0;
            flag = head;
            while (flag != NULL)
            {
                ++flags;
                flag = flag->next;
            }
            printf("这个链表有%d个数据\n", flags);
            return flags;
        default:
        {
            single_list* p;
            p = head;
            int z = 0;
            printf("\nnumber           point        self_point\n");
    
            do
            {
                printf("%d:%d,%10d,%10d\n", ++z, p->number, p->next, p);
                p = p->next;
    
            } while (p != NULL);
        }
        }
        return 1;
    }
    //打印功能表
    void operation()
    {
        printf("\'1\'在末尾增加值  \'2\'指定位置增加值\n\'3\'删除指定值\'4\'修改固定位置的值\n\'5\'链表反转\'9\'输出链表长度\n\'11\'打印当前链表");
    }
    
    single_list* reverse(single_list* head) //递归逆转链表
    {
        if (head == NULL || head->next == NULL) {
            return head;
        }
        single_list* ret = reverse(head->next);
        head->next->next = head;
        head->next = NULL;
        return ret;
    
    
    }
    //迭代逆转链表,问题出现在else程序段
    single_list* diedai(single_list* head) {
        single_list* cur = NULL, * pre = head;
        while (pre != NULL) {
            single_list* t = pre->next;
            pre->next = cur;
            cur = pre;
            pre = t;
        }
        return cur;
       
    }
    
    int reverseList(single_list* head)
    {
        if (head == NULL)
        {
            printf("你好"); return 1;
        }
        single_list* cur, * pnext, * pre;//建立三个指针,当前指针,下一个指针,上一个指针
        cur = head;
        pre = NULL;
        while (cur) {
            pnext = pre->next;
            cur->next = pre;
            pre = cur;
            cur = pnext;
            printf("标记\n");
        }
        C.head = pre;
        return 1;
    
    }
    
    
    
    void main()
    {
        int a = 1;
        printf("please creat a link:\n");
        creat();//创建link;
        operation();
        fflush(stdin);
    
        int llll = 0;
        while (a != 10)
        {
            fflush(stdin);
            printf("\n请输入对应数字执行对应操作\n");
    
            //        if (llll++!=0)
            //          operation();
            scanf("%d", &a);
            switch (a)
            {
            case 6:
                reverseList(C.head);
                //                diedai(C.head);
                break;
            case 5:
            {
                C.head = reverse(C.head);
                break;
            }
            default:
            {
    
                if (a > 0 && a <= 11)
                    print_link(C.head, a);
                else
                    printf("error!\n");
            }
            }
    
        }
    }
    
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 5月9日
  • 已采纳回答 5月1日
  • 修改了问题 4月30日
  • 创建了问题 4月30日

悬赏问题

  • ¥15 在hololens1上运行unity项目只有空窗口
  • ¥25 TABLEAU PREP无法打开
  • ¥15 百度帐号问题/centos
  • ¥15 关于#c语言#的问题:求完整代码条件好说
  • ¥100 HALCON DELPHI
  • ¥15 (需要远程,AI不回)VB6二进制文件转换成功,但是C#转换总是失败
  • ¥15 关于#matlab#的问题:有没有什么其他办法能够保证不退出进程(相关搜索:matlab调用)
  • ¥15 依据报错在原代吗格式的基础上解决问题
  • ¥15 在虚拟机中安装flash code
  • ¥15 单片机stm32f10x编写光敏电阻调节3.3伏大功率灯亮度(光强越大灯越暗,白天正常光强灯不亮,使用ADC,PWM等模块)望各位找一下错误或者提供一个可实现功能的代码