欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C语言线性表之链表

程序员文章站 2022-06-06 13:34:45
...

C语言线性表之链表

单链表定义

线性表的链式存储又称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素。为了建立数据之间

的线性关系,对每个链表结点,除存放元素自身之外,还需存放一个指向其后继的指针。单链表结点,data为数据域,存放数据;next为指针域,存放其后继结点的地址。

单链表中结点类型描述如下

typedef struct LNode
{
	ElemType data;
	struct LNode *next;
}LNode, *LinkList;

存储结构如下

通常用头指针来表示一个单链表,如单链表L,头指针为NULL时表示一个空表。此外,为了操作上的方便,在单链表第一个结点之前附加一个结点,称为头结点。头结点的数据域可以不设任何信息,也可以用来记录表长等数据。头结点的指针域指向线性表的第一个元素结点如图所示

C语言线性表之链表

引入头结点,可以带来两个优点:

  • 由于开始结点的位置被存放在头结点的指针域当中,所以在链表的第一个位置上的操作和在表的其他位置上的操作一样,不需要进行特殊处理。
  • 无论链表是否为空,其头指针都指向头结点的非空指针,因此空表和非空表也得到了统一。

单链表基本操作实现

头插法建立单链表

C语言线性表之链表

用这个为例,此时表中已有一个元素a1,现在要将a2元素插入表中。就需要将头结点的next指向a2,将a2的next指向a1。现在将元素1所在的结点称为S1,新元素2所在的结点称为S2。

刚开始表中只有a1元素时
L->next = S1
S1->next = NULL
现在元素2将要加入到表中,改变成
S2->next = L->next
L->next = S2

上代码

创建链表和插入结点操作

LinkList Create_List(LinkList &L)
{
	// 此函数用来创建单链表
    L = (LinkList) malloc(sizeof(LNode));
    L->next = NULL;
}
void Inser(LinkList &L, int e)
{
    // 此函数用来将元素e插入到表L当中
    LNode *s;
    s = (LNode *)malloc(sizeof(LNode));
    s->next = L->next;
    L->next = s;
}

按序号查找结点值

从单链表中第一个结点开始查找,顺着指针next一路往下搜索,直至找到第i个结点

LNode *GetElem(LinkList &L, int i)
{
	// 此函数用来查找表中第i个元素并将结点返回
    int j = 1; // 计数
    LNode *p = L->next;
    if(i == 0)
        return L;
    if(i < 1)
        return NULL; // 没有这个结点
    while(p && i > j)
    {
        p = p->next;
        j++;
    }
    return p;
}

按值查找表结点

LNode *Find(LinkList &L, int e)
{
	// 此函数用来查找某个值得结点
    LNode *p = L->next;
    while(p != NULL && p->data != e)
        p = p->next;
    return p;
}

删除结点操作

C语言线性表之链表

以上图为例子,表中此时有5和6两个元素,现在要将第2这个元素5删除
就只需要找到第2个元素的前一个结点
p = GetElem(LinkList L, i-1)
q = p->next
p->next = q
void Delete(LinkList &L, int i)
{
    LNode *q, *p; 
    p = GetElem(L, i-1);
    q = p->next;
    p->next = q;
}

总代码

#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode, *LinkList;

LinkList Create_List(LinkList &L)
{
    L = (LinkList) malloc(sizeof(LNode));
    L->next = NULL;
}
void Inser(LinkList &L, int e)
{
    LNode *s;
    s = (LNode *)malloc(sizeof(LNode));
    s->data = e;
    s->next = L->next;
    L->next = s;
}
LNode *GetElem(LinkList &L, int i)
{
    int j = 1; // 计数
    LNode *p = L->next;
    if(i == 0)
        return L;
    if(i < 1)
        return NULL; // 没有这个结点
    while(p && i > j)
    {
        p = p->next;
        j++;
    }
    return p;
}
LNode *Find(LinkList &L, int e)
{
    LNode *p = L->next;
    while(p != NULL && p->data != e)
        p = p->next;
    return p;
}
void Delete(LinkList &L, int i)
{
    LNode *q, *p;
    p = GetElem(L, i-1);
    q = p->next;
    p->next = q->next;
    free(q);
}
int main()
{
    LinkList L;
    L = Create_List(L);
    Inser(L, 5);
    Inser(L, 6);
    Inser(L, 16);
    LNode *s = GetElem(L, 2);
    printf("%d\n", s->data);
    Delete(L, 1);
    s = GetElem(L, 1);
    printf("%d\n", s->data);
    LNode *s1 = Find(L, 5);
    printf("%d\n", s1->data);
    return 0;
}

顺序表