线性表:链式储存结构(单链表)

Posted 天赋不够努力来凑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表:链式储存结构(单链表)相关的知识,希望对你有一定的参考价值。

一、定义

每个元素(结点)分为数据域和指针域,数据域储存数据信息,指针域储存指向后继元素的指针。所以不用把所有元素像顺序结构一样连续储存,因为有指针域,所以我们就能将数据链接在一起。

二、特点

(1)、指向第一个节点的指针叫头指针,最后一个结点指针域为空,通常用NULL表示。
(2)、有时为了更好地操作链表,会在第一个结点前设置一个头结点,该结点数据域为空(有时存放链表长度),指针域指向第一个结点,此时头指针指向头结点。

三、储存结构表示

typedef int ElemType;
typedef struct Node

    ElemType data;//数据域
    struct Node *next;//指针域
Node,*LinkList;

四、其他操作(针对带头结点单链表)

1、整表创建
(1)、头插法
特点:始终让新结点在第一个结点的位置

void CreateListHead(LinkList *L,int n)

    LinkList p;//插入结点p
    ElemType data;//插入结点p的数据
    *L=(LinkList)malloc(sizeof(Node));//给头结点分配内存
    (*L)->next=NULL;//此时只有一个头结点,所以头结点指针域为空
    for(int i=0;i<n;i++)
    
        cin>>data;
        p=(LinkList)malloc(sizeof(Node));//给插入结点p分配内存
        p->data=data;
        //头插法
        p->next=(*L)->next;
        (*L)->next=p;
    

(2)、尾插法
特点:新结点插在最后一个结点后面

void CreateListTail(LinkList *L,int n)

    LinkList p,r;//定义插入结点p和尾部指针
    ElemType data;
    *L=(LinkList)malloc(sizeof(Node));//为头结点分配内存
    (*L)->next=NULL;//此时只有一个头结点,所以头结点指针域为空
    r=*L;//使尾部指针指向尾部结点
    for(int i=0;i<n;i++)
    
        p=(LinkList)malloc(sizeof(Node));//给插入结点p分配内存
        cin>>data;
        p->data=data;
        r->next=p;
        r=p;//始终让尾部指针指向尾部结点
    
    r->next=NULL;//让尾部结点指针域为空,因为它无后继结点

2、销毁链表

void ClearList(LinkList *L)

    LinkList p,q;//创建指针p,q;
    p=(*L)->next;//p始终指向要销毁的结点
    while(p)
    
        q=p->next;//q始终保存要销毁结点的后继结点
        free(p);
        p=q;
    
    (*L)->next=NULL;//头结点指针域为空

3、读取链表

int getElem(LinkList L,int i,ElemType *e)

    int j=1;//定义一个计数器
    LinkList p=L->next;//使指针p指向第一个结点
    while(p&&j<i)
    
        p=p->next;//指针指向下一个结点
        ++j;
    
    if(!p||j>i)
        return 0;
    *e=p->data;
    return 1;

4、链表的插入

//在第i个位置前插入新结点
int ListInsert(LinkList *L,int i,ElemType e)

    int j=1;//定义一个计数器j
    LinkList p=*L;//让指针p指向头结点
    LinkList s;//要插入的新结点s
    while(p&&j<i)
    
        p=p->next;
        ++j;
    
    if(!p||j>i)
        return 0;
    s=(LinkList)malloc(sizeof(Node));
    s->data=e;
    s->next=p->next;
    p->next=s;
    return 1;

5、删除链表结点

int ListDelete(LinkList *L,int i,ElemType *e)

    int j=1;//定义一个计数器j
    LinkList p=(*L)->next;//使指针p指向第一个结点
    LinkList q;
    while(p&&j<i)
    
        p=p->next;
        ++j;
    
    if(!p||j>i)
        return 0;
    *e=p->data;
    q=p->next;//使指针q指向要删除结点的下一个结点
    p->next=q->next;
    free(p);
    return 1;

五、链表与数组优缺点

(1)、用数组进行插入删除时,时间复杂度为o(n),用链表进行插入删除时,时间复杂度为o(1),所以要进行大量插入删除时,最好使用链式结构。
(2)、查找时,数组时间复杂度为o(1),链表时间复杂度为o(n),所以要进行频繁查找时,最好使用数组结构。
(3)、线性表元素变化较大或未知数量最好使用链式结构节省空间。

以上是关于线性表:链式储存结构(单链表)的主要内容,如果未能解决你的问题,请参考以下文章

线性表的链式存储结构 ( 链表 )

数据结构与算法-线性表之循环链表

《数据结构 - 线性表》链式存储 (单链表)

数据结构--线性表的链式存储之循环单链表

数据结构第三篇——线性表的链式存储之单链表

数据结构与算法学习笔记 线性表Ⅱ