C 语言链表

  1. 链表的概念

问题?

假如: 做一个班级信息管理系统, 统计班级学生的信息。而我们事先不知道班级人数, 或者知道人数,

但是中间人员可能发生变化: 比如有新同学加入, 有同学请假, 又或者我们需要统计班级的平均

成绩等等

假如: 要做一个类似 QQ、 飞秋类似的通信软件, 其中有一个功能, 类似用户上下线检测: 有新的

用户上线、 下线,实时更新显示, 可以实时查询在线状态、 按姓名排序等

以上问题如何使用学过的 C 语言知识处理呢?

使用数组远远不能达到我们的要求

因为数组必须实现确定大小, 不能实现动态申请、 释放

使用 malloc 动态内存分配也无法实现

malloc 申请的空间, 不能实现局部申请、 释放

这里我们学习一种很强大也很重要的数据结构——链表

1.1定义

链表是一种物理存储上非连续, 数据元素的逻辑顺序通过链表中的指针链接次序, 实现的一种线性存储结构。

1.2特点

链表由一系列节点(链表中每一个元素称为节点) 组成, 节点在运行时动态生成(malloc) , 每个节点包括两个部分:

一个是存储数据元素的数据域

另一个是存储下一个节点地址的指针域

  1. 链表的构成

链表由一个个节点构成, 每个节点一般采用结构体的形式组织, 例如:

typedef struct student
{
    int num;
    char name[20];
    struct student *next;
}STU;

2.1链表节点分为两个域

数据域: 存放各种实际的数据, 如: num、 score 等

指针域: 存放下一节点的首地址, 如: next 等.

  1. 链表的创建  

typedef struct student
{
    int num;
    int score;
    char name[20];
    struct srudent *next;
}STU;

vodi linkCreat(STU**p_head,STU*p_new)
{
    STU *p_mov = *p_head;
    if(*p_mov == NULL)
    {
        p_mov->next=p_new;
        p_new->next = NULL;
    }
    else 
    {
        while(p_mov->next!=NULL)
        {
            p_mov=p_mov->next;
        }
        p_mov->next=p_new;
        p_new->next = NULL;
    }
}

int main()
{
    STU *head =NULL,*p_new=NULL;
    int num,i;
    printf("请输入链表的初始个数:\n");
    scanf("%d",&num);
    for(i=0;i<num;i++)
        {
            p_new = (STU*)(malloc(sizeof(STU)));
            printf("请输入学号、分数、姓名:\n");
            scanf("%d %d %s",&p_new->num,&p_new->score,&p_new->name );
            link_creak(&head,p_new);
    }
}
  1. 链表的遍历

void link_print(STU *head)
{
    STU *p_mov = haed;
    while(p_mov!=NULL)
    {
        printf("学号:%d,分数:%d,姓名:%s",p_mov->num,p_mov->score,p_mov->name);
        p-mov=p_mov->next;
    }
}
  1. 链表的释放

void link_free(STU*head)
{
    STU*p_mov=head;
    whlie(head!=NULL)
    {
        p_mov=head;
        head=head->next;
        free(p_mov);
    }
}
  1. 链表节点的查找

STU * link_search_num(STU*head,int num)
{
    STU*p_mov=head;
    while(p_mov!=NULL)
    {
        if(p_mov->num==num)
        {
            return p_mov;
        }
        p_mov=p_mov->next;
    }
    return NULL;
}
  1. 链表节点的删除

void link_delete_num(STU**head , int num)
{
    STU*p_mov=*head;
    STU*pb=p_mov;

    if(*p_head ==NULL)//链表为空,不用删
    {
        printf("链表为空,没有您要删的节点");\
        return ;
    }

    if(p_mov->num==num)//要删除的是头节点
    {
        *head=*head->next;
    }
    else 
    {
        p_mov=p_mov->next;
    }
    while(p_mov!=NULL)
    {
        if(p_mov->num==num)//找到要删除的节点
        {
        pb->next=p_mov->next;
        free(p_mov);
        }
        pb=p_mov;
        p_mov=p_mov->next;
    }
}
  1. 链表中插入一个节点

头插法:

void link_insert(STU**head,STU*p_new)
{
    STU*p_mov=*head;
    if(*head==NULL)//空链表
    {
        *head=p_new;
        p_new->next==NULL;
    }
    p_new->next=p_mov;
    *p_head=p_new;
}

尾插法:

void link_insert(STU**head,STU*p_new)
{
    STU*p_mov=*head;
    if(*head==NULL)//空链表
    {
        *head=p_new;
        p_nw->next==NULL;
    }
    while(p_mov->next=NULL)
    {
        p_mov=p_mov->next;
    }
    p_mov->next=p_new;
    p_new->next=NULL:
}
  1. 链表排序

void link_order(STU*head)
{
    STU*pb,*pf,temp;
    pf=head;
    if(head==NULL)//空链表
    {
        printf("空链表不用排序\n");
    }
    if(head->next==NULL)
    {
        printf("只有一个节点也不用排序\n")
    }
    while(pf->next!=NULL)
    {
        pb=pf->next;
        while(bp!=NULL)
        {
            if(pf->num>pb->num)
            {
                temp=pb;
                pb=pf;
                pf=temp;
                
                temp->next=pb->next;
                pb->next=pf->next;
                pf->next=temp->next;
            }
            pb=pb->next;
        }
        pf=pf->next;
    }
}
  1. 链表逆序

STU* link_reverse(STU*head)
{
    STU*pf,*pb,*r;
    pf=head;
    pb=pf->next;
    while(head==NULL)printf("空链表\n");
    
    while(pb!=NULL)
    {
        r=pb_next;
        pb->next=pf;
        pf=pb;
        pb=r;
    }
    head->next=NULL;
    head=pf;
    return head;
}
  1. 双向链表的创建

typedef struct student
{
    int num;
    int score;
    char name[20];
    struct student *front;
    struct student *next;
}STU;

void double_link_create(STU**head,STU*p_new)
{
    STU *p_mov=*head;
    if(*head==MULL)
    {
        *head = p_new;
        p_new->next = NULL:
        p_new->front=NULL;
    }
    else
    {
        while(p_mov->next!=NULL)
        {
            p_mov=p_mov->next;
        }
        p_mov->next=p_new;
        p-new->next=NULL:
        p_new->front=p_mov;
    }
}
  1. 双向链表节点的删除

void double_link_delete_num(STU**head,int num)
{
    STU*pb,*pf;
    pb=*head;
    if(*head == NULL)
    {
        printf("空链表\n");
        return ;
    }
    while(pb->num==num&&pb->next!=NULL)
    {
        pb=pb->next;
    }
    if(pb->num==num)
    {
        if(pb==*head)
        {
        head=head->next;
        head->front=NULL;
        }
        else
        {
            if(pb->next!=NULL)//要删除的是中间节点
            {
                pf=pb->front;
                pf->next=pb->next;
                (pb->next)->front=pf;
            }
            else//要删除的是尾节点
            {
                pf=pb->front;
                pf->next=NULL;
            }
        }
    }
}
  1. 双向链表插入节点

头插法:

void double_link_insert(STU**head,STU*p_new)
{
    if(*head==NULL)
    {
        *head = p_new;
        p_new>next=NULL;
        p_new->front=NULL;
    }
    else 
    {
        p_new->next = *head;
        p_new->fornt=NULL;
        *head = p_new;
    }
}

尾插法:

void double_link_insert(STU**haed,STU*p_new)
{
    STU*p_mov=*head;
    if(*head==NULL)
    {
        *head = p_new;
        p-new>next=NULL;
        p_new->front=NULL;
    }
    while(p_mov->next!=NULL)
    {
        p_mov=p_mov->next;
    }
    p_mov->next=p_new;
    p_new->front=p_mov;
    p_new->next =NULL:
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值