C语言程序设计 细节总结(链表)

12 链表

12.1 链表概述

1.采用动态存储分配的一种重要数据结构,一个链表中存储的是一批同类型的相关联数据
2.动态分配时,每个结点之间可以不连续,结点之间的联系可以用指针实现,每个结点分两个域:数据域和指针域

12.2 处理动态链表所需函数(需要包含头文件stdlib.h)

1.分配内存空间函数malloc()
(1)函数调用形式:(类型说明符*)malloc(size)
(2)malloc函数要求系统在内存分配一块长度为size字节的连续区域,函数返回值为区域首地址
(3)函数返回的指针是无类型的,(类型说明符*)表示把返回值强制转换为该类型指针
(4)例如,p=(char*)malloc(100); //表示分配100个字节的内存空间,强制转换为字符数组类型,函数返回值为指向该字符数组的指针,把该指针赋给指针变量p
2.分配内存空间函数calloc()
(1)函数调用形式:(类型说明符*)calloc(n,size)
(2)calloc函数要求系统在内存动态存储区分配n块长度为size字节的连续区域
(3)例如,ps=(struct stu *)calloc(2,sizeof(struct stu));
3.释放内存空间函数free()
(1)函数调用形式:free§
(2)释放指针变量p所指向的一块内存区域

12.3 单链表基本操作

1.建立链表
(1)调用malloc()函数向系统申请一个结点的存储空间
(2)输入该结点的值,并把该节点的指针成员设置为0
(3)把该结点加入链表中,如果链表为空,则该结点为链表头结点,否则该结点加入表尾
2.链表查找
3.插入结点
(1)调用malloc()函数分配一个结点空间,并输入新节点的值
(2)查找合适的插入位置
(3)修改相关节点的指针域
4.删除结点
(1)从表头结点开始,确定要删除结点的地址q,以及q的前一个结点p的地址
(2)如果q为头结点,删除后应修改表头指针head,否则修改结点p的指针域
(3)回收结点q的空间

代码:

#include<stdio.h>
#include<stdlib.h>
struct node  //定义结点结构
{
    int num;
    int score;
    struct node *next;
};
//1.创建链表
struct node *creat(struct node *head,int n)
{
    struct node *p,*q;
    for(int i=1; i<=n; i++)
    {
        q=(struct node *)malloc(sizeof(struct node)); //申请结点空间
        scanf("%d%d",&q->num,&q->score);  //输入结点值
        q->next=NULL;  //指针成员设为NULL
        if(head==NULL)  //如果链表为空,该结点为链表头结点
        {
            head=q;
        }
        else  //否则加入表尾
        {
            p->next=q;
        }
        p=q;  //q赋给p,为下一次q开辟空间保留上一次结点地址
    }
    return head;
};
//2.输出链表
void print(struct node *head)
{
    struct node *p;
    p=head;
    while(p!=NULL)
    {
        printf("%d %d\n",p->num,p->score);
        p=p->next;
    }
}
//3.链表查找
void find(struct node *head)
{
    int x;
    printf("请输入要查找的序号:\n");
    scanf("%d",&x);

    struct node *p;
    p=head;
    while(p!=NULL&&p->num!=x)
    {
        p=p->next;
    }
    if(p)
    {
        printf("num=%d\tscore=%d\n",p->num,p->score);
    }
    else
    {
        printf("%d not be found!\n",x);
    }
}
//4.插入结点
struct node *insert(struct node *head)
{
    struct node *p,*q,*p1;
    q=(struct node*)malloc(sizeof(struct node)); //为新结点申请空间
    printf("请输入要插入的结点(序号、分数):\n");
    scanf("%d%d",&q->num,&q->score);

    //在空表中插入
    if(head==NULL)
    {
        q->next=NULL;
        head=q;
        return head;
    }
    //新结点插入表头之前
    if(head->num > q->num)
    {
        q->next=head;
        head=q;
        return head;
    }
    //在链表中查找插入位置
    p=head;
    p1=head->next;
    while(p1!=NULL&&p1->num < q->num)
    {
        p=p1;  //循环结束后p是上一结点
        p1=p1->next;  //循环结束后p1是插入位置下一结点
    }
    q->next=p1;
    p->next=q;
    return head;
};
//5.删除结点
struct node *dele(struct node *head)
{
    int i,x;
    printf("请输入要删除的序号:\n");
    scanf("%d",&x);

    struct node *p,*q;
    q=head;
    while(q!=NULL&&q->num!=x)
    {
        p=q;  //保留上一结点地址
        q=q->next;
    }
    if(q==NULL)
    {
        printf("not found!");
    }
    else
    {
        if(q==head)
        {
            head=q->next;
        }
        else
        {
            p->next=q->next;
        }
        free(q);
    }
    return head;
};
int main()
{
    struct node *head=NULL;  //定义表头指针

    head=creat(head,5);

    print(head);

    find(head);

    head=insert(head);
    print(head);

    head=dele(head);
    print(head);
    return 0;
}
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值