建立单项链表的练习

单项链表的建立和节点的删除

注意:

  1. scanf(" %c",&ans); //这个位置的空格不能省略。在使用%c格式读入字符时,空格字符和转义字符(包括回车)都会被当成有效字符,这是使用scanf()输入%c格式时需要格外注意的一点。
    解决方式:在%c前面加入一个空格,忽略前面数据输入时存入缓冲区的回车符,避免被后面的字符型变量当做有效字符读入。
  2. if (head == NULL) //忘记写双等号了
  3. pr->next = p; //链上这个要放在else里面,两种情况,是或者不是头结点
  4. 竟然这些代码放到了else 中的while里面,这样如果是头结点那么就不会添加节点了,逻辑不够清晰。这是链上之后,向新结点添加数据,所以要放在if else条件判断之外,while循环的作用只是将pr的指向移动到尾结点(pr->next为空的节点)。
    printf(“please input data:”);
    scanf(" %d", &da);
    p->data = da;
    p->next = NULL;
    return head;
    5.这俩顺序不能换,要先将p保存到pr中,然后再顺着链表找下一个
    pr = p;
    p = p->next;
    6.free§;//既然两个分支都有 ,那么就放到外面吧
    7.head = DelNod(head,da); 在不把head作为返回值时候,这个程序就无限循环,可以看看head地址.。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct link *AppNod(struct link *head);
void DisLin(struct link *head);
void DelMem(struct link *head);
struct link *DelNod(struct link *head, int data);
struct link{
    int data;
    struct link *next;
};
int main()
{
    struct link *head = NULL;
    char ans;
    int i=0;
    int da;
    printf("Do you want to add node to the link?(y/n)");
    scanf(" %c",&ans);
    while (ans == 'y')
    {
        i=i+1;
        head = AppNod(head);
        DisLin(head);
        printf("Do you want to add node to the link?(y/n)");
        scanf(" %c",&ans);  //这个位置的空格不能省略
    }

    printf("The total number of nodes is %d\n",i);
    printf("Please input the data that you want to delete:");
    scanf("%d",&da);
    head = DelNod(head,da);  //在不把head作为返回值时候,这个程序就无限循环,为啥?
    DisLin(head);
    DelMem(head);
}
struct link *AppNod(struct link *head)
{
    struct link *pr = head, *p = NULL;
    int da;
    p = (struct link *)malloc(sizeof(struct link));
    if (p == NULL)
    {
        printf("There is no enough memory to allocate.");
        exit(0);
    }
    warning: suggest parentheses around assignment used as truth value [-Wparentheses]|
    if (head == NULL) //忘记写双等号了
    {
        head = p;
    }
    else
    {
        while (pr->next != NULL)
        {
            pr = pr->next;
        }
        pr->next = p;  //链上这个要放在else里面
    }
    //竟然这些代码放到了while里面,这样如果是头结点那么就不会添加节点了
    printf("please input data:");
    scanf(" %d", &da);
    p->data = da;
    p->next = NULL;
    return head;
};
//忘记加void也会警告,函数返回值的默认类型是整型,与函数原型声明中不同会报警
void DisLin(struct link *head)
{
    struct link *p = head;
    int j=1;
    while (p != NULL)
    {
        printf("%d\t%d\n",j,p->data);
        p = p->next;
        j++;
    }
}
void DelMem(struct link *head)
{
    struct link *p = head, *pr = NULL;
    while (p != NULL)
    {
        pr = p;
        p = p -> next;
        free(pr);
    }
}
struct link *DelNod(struct link *head, int data)
{
    struct link *p = head, *pr = head;
    if (p == NULL)
    {
        printf("link is empty");
        return head;
    }
    while (p->data != data && p->next != NULL)
    {
        pr = p;        //这俩顺序不能换,要先将p保存到pr中,然后再顺着链表找下一个
        p = p->next;
    }
    if (p->data == data)
    {
        if(p == head)
        {
            head = p->next;
        }
        else
        {
            pr->next = p->next;
        }
        free(p);//既然两个分支都有 ,那么就放到外面吧
    }
    else
    {
        printf("can't find the node");
    }
    return head;
}

附注:程序参考《C语言程序设计第三版》-苏小红P360-364,将删除链表节点的函数放到了主函数中,相比于书中P360代码,本文代码主函数增加了一个节点删除功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值