c语言链表的简介和使用

目录

一、分类

1.静态链表

(1)使用条件:

(2)实例:

2.动态链表(用各个函数来实现----模块化思想)

(1)函数要求

(2)功能:链表的建立、插入、删除


一、分类

1.静态链表

(1)使用条件:

链表长度固定且结点个数较少时使用

(2)实例:

《注:静态链表 就是以  结构体  为结点组成的链表 结构体中 包含 数据域  和指针域  指针域用  指向下一个结点

#include<stdio.h>
struct student
{
    int num;
    char name[20];
    float score;
    struct student * next;
};
void main()
{
    struct student a = { 1011,"zhangsan",562},b = { 1012,"lisi",520},c = { 1013,"wangyusheng",542};
    struct student *head,*p;
    head = &a;
    a.next = &b;
    b.next = &c;
    c.next = NULL;
    for (p = head;p!=NULL; p= p->next)
    {
        printf("%5d %8s %6.1f\n",p->num,p->name,p->score);
    }
}

 注:在静态链表中就是将一个结构体来当做一个结点 ,以此来实现静态链表的组成

2.动态链表(用各个函数来实现----模块化思想)

(1)函数要求

<1> malloc 函数

函数原型: void * malloc(unsinged size)

功能:在内存中动态存储区中分配 size字节的连续空间 ,成功时:返回值为分配存储区的起始地址  分配不成功时:返回 null

实例:

char *p;
p = (char*) malloc (8);

<2> calloc 函数

函数原型:void * calloc(unsinged  n ,unsinged unsinged size)

功能:在内存的动态存储区中分配n个长度size 字节的连续空间,成功时:返回值为分配存储区的起始地址  分配不成功时:返回 null

例如:

char *p;
p = (char * p) calloc (2,20);

<3>free 函数

函数原型:void free(void * p)

功能:释放p所指向的内存空间

int n ,*p;
scanf("%d",&n);
p = (int * ) malloc ( n * sizeof(int));
free ( p );

(2)功能:链表的建立、插入(头插法、尾插法)、删除

<1>链表的建立

思想:开辟N个结点,没开辟一个结点,每个结点都让p1指向新节点,p2 指向当前的表尾结点,把p1所指向的节点连接到p2所指向结点的后面

实例:

#include <malloc.h>
struct student * create(int n )
{
 struct student * head =NULL,*p1,*p2;
 int i;
 for (i = 1;i <= n; i ++)
 {
  p1 = (struct student *) malloc (sizeof (struct student));
  printf("请输入第%d 个学生的学号和成绩:\n",i);
  scanf("%d%f",&p1 ->num,&p1-> score);
  p1 ->next= NULL;
  if (i == 1):
    head = p1;
  else
    p2 -> next = p1;
   p2 = p1;
 }
return(head);
}

<2> 链表的动态删除

想法:

要删除一个结点,只需要从第一个结点出发沿着链表搜索,找到待删除的点后,修改该节点的前驱结点(前一个结点)的指针域,使其指向待删除结点的后继结点(后一个结点)

 实例:(删除指定学号的学生结点,以头指针和学号作为参数)

#include<stdio.h>
struct student * del(struct student *head,int num)
{
    struct student *p1,*p2;
    if (head == NULL)
    {
        printf("原链表为空! \n");
        return (NULL);
    }
    else
    {
        p1 = head;
        while(p1->num != num  &&  p1->next != NULL)
        {
            p2 = p1;
            p1 = p1->next;
        }
        if (p1->num == num)
        {
            if (p1 == head)
                head = p1->next;
            else
                p2->next = p1->next;
            printf("学号为 %d 的学生已经被删除!\n",num)
        }
        else
            printf("学号为 %d 的学生不存在! \n",num);
    }
    return (head);
};

<3>链表的插入

  头插法

  思路:将新的结点插入已知的链表的第一个结点之前

  例如:

template <typename T>
node<T> *Inser_head(node<T>*list , T value)
{
    node<T> *pnode;
    pnode = new node<T>;
    pnode ->value = value;
    pnode ->next = list->next;
    if (list ->next != nullptr)
        list->next->prev = pnode;
    pnode->next = list;
    list->next = pnode;
    return pnode;
}

尾插法

思路:

保存一个末尾指针,插入时先将末尾指针所指向的结点的后继设置为新的结点,然后更新末尾指针为新的结点

例如:

template<typename T>
node<T> *insert_tail(node<T>*list,T value,node<T>*tail)
{
    node<T> *pnode;
    pnode = new node;
    pnode ->next= nullptr;
    pnode->value = value;
    tail->next = pnode;
    return pnode;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小捣蛋.

建议你还是留着你的小钱吧!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值