1.26学习总结2

本文详细介绍了链表的概念,包括单向链表的结构、特点以及操作(如读取、插入和删除),并与数组进行了对比。同时提到了双向链表的特点。
摘要由CSDN通过智能技术生成

链表

链表的概念

一种常见的重要的数据结构,是动态的进行存储分配的一种结构。用数组存放数据时,需先定义固定的数组长度,链表则根据需要开辟内存单元。

定义

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

如图为一种链表(单向链表)的结构:

                head                 1249                    1356                    1475                     1021

特点

  • 链表有一个“头指针”变量 ,如图head,它存放一个地址,该地址指向一个元素。链表中每一个元素称为结点,每个结点都包括两部分:(1)存储数据元素的数据域(2)存储下一个节点地址的指针域head 指向第1个元素,第1个元素又指向第2个元素,直到最后一个元素,该元素不再指向其他元素,它称为“表尾”,它的地址部分放一个“NULL”(空地址),链表到此结束 。
  • 链表中各元素在内存中的地址可以是不连续的 。
  • 作用:通过结点把离散的数据链接在一起,组成一个表。

链表的构成

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

结点

数据域:存放各种实际的数据。

指针域:存放下一结点的首地址。(指针域中储存的信息称为指针或链)

struct student
{
    //数据域
    int num;
    char name[20];
    //指针域
    struct student *next;//next是指针变量,指向结构体变量
 };

头指针

链表中第一个结点的存储位置叫做头指针。

NULL

线性链表的最后一个结点指针为“空”(用“NULL”或“^"表示)

头结点

为了更加方便地对链表进行操作,在单链表的第一个结点前附设一个结点,称为头结点。

头结点的数字域可以不储存任何信息,也可以储存如线性表的长度等附加信息。

头指针与头结点异同

链表与数组的对比

数组中的成员及链表中的结点

链表

通过节点把离散的数据链接成一个表,通过对节点的插入和删除操作从而实现对数据的存取。链表中各元素在内存中的地址可以不连续

数组

通过开辟一段连续的内存来存储数据,有起始地址。

单链表的读取

获得链表第i个数据

算法思路

1.声明一个结点p指向链表第一个结点, 初始化j从1开始;
2.当j<i时,就遍历链表, 让p的指针向后移动,不断指向下一结点, j累加1;
3.若到链表末尾p为空,则说明第i 个元素不存在;
4.否则查找成功,返回结点p的数据。

代码
Status GetElem (LinkList L,int i,ElemType *e)
{
    int j;
    LinkList p;      //声明一结点p
    p=L->next;       //让p指向链表L的第一个结点
    j=1;             //计数器
    while(p&&j<i)    //p不为空或者计数器j还没有等于i时,循环继续
    {
        p=p->next;   //让p指向下一个结点
        ++j;
    }
    if(!p||j>i)
        return ERROR;//第i个元素不存在
    *e=p->data;      //取第i个元素的数据
    return OK;
}

单链表的插入与删除

链表第i个数据插入或删除结点

单链表的插入

s->next=p->next;
p->next=s;
算法思路

1.如果查找成功,生成一个空结点s;

2.将数据e赋值给s->data;

3.再执行s->next=p->next;p->next=s;

4.最后返回。

代码
Status GetElem (LinkList *L,int i,ElemType e)
{
    int j;
    LinkList p,s;      
    p=*L;       
    j=1;             //计数器
    while(p&&j<i)    //p不为空或者计数器j还没有等于i时,循环继续
    {
        p=p->next;   //让p指向下一个结点
        ++j;
    }
    if(!p||j>i)
        return ERROR;//第i个元素不存在
    s=(LinkList)malloc(sizeof(Node));
                     //生成新结点
    s->data=e;       
    s->next=p->next;
    p->next=s;
    return OK;
}

单链表的删除

p->next=p->next->next
算法思路

1.如果查找成功,将欲删除的结点p->next赋值给q ;

2.再执行p->next=q->next;

3.将结点q中的数据赋值给e;

4.释放结点q;

4.最后返回。

代码
Status GetElem (LinkList *L,int i,ElemType *e)
{
    int j;
    LinkList p,s;      
    p=*L;       
    j=1;             //计数器
    while(p->next&&j<i)    //p不为空或者计数器j还没有等于i时,循环继续
    {
        p=p->next;   //让p指向下一个结点
        ++j;
    }
    if(!p||j>i)
        return ERROR;//第i个元素不存在
    q=p->next;       
    p->next=q->next; 
    *e=q->data;      //将q结点中数据给e
    free(q);         //回收此结点,释放内存
    return OK;
}

双向链表

 结点中有两个结点指针,分别指向前后两个结点,其它与单向链表完全一样。

  • 22
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值