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

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

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

我想要达到的结果

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

代码写的有点乱
(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");
        }
        }

    }
}



谢谢呀,我明白自己哪错了,非常感谢,另外我是有一个迭代的逆转函数,不过刚才我已经修改好了,可以运行了,非常感谢。

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632