数据结构之线性表的链式存储

189 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、线性表链式存储结构

无需提前确定存储空间的容量,可以用一组任意的存储单元存储线性表的数据元素。

二、链式存储的定义

n个结点链结成一个链表,一个结点由一个数据域和指针域组成,其中数据域存储数据元素的信息,指针域存储直接后继的位置。必须有一个头指针指向第一个结点,最后一个结点的指针为NULL。

线性表中结点的定义
typedef struct Node
{
    ElementType data;
    struct Node* next;
}Node;                        /*结点的定义*/

typedef struct Node* LinkList;/*线性表的定义*/

三、链式存储的相关操作实现

1.线性表的初始化

生成头结点,并指向头结点

/*线性表的初始化*/
int InitList(LinkList *L)
{
    *L=(LinkList)malloc(sizeof(Node));/*产生头结点,并指向此头结点*/
    if(!(*L))
    return ERROR;

    (*L)->next=NULL;                  /*指针域为空*/

    return OK;
}

2.线性表的清空

/*线性表的清空*/
int ClearList(LinkList *L)
{
    LinkList p,q;
    p=(*L)->next;

    while(p)
    {
        q=p->next;
        free(p);
        p=q;
    }
    (*L)->next=NULL;

    return OK;
}

3.获得线性表中数据元素的个数

/*获得线性表中元素的个数*/
int ListLength(LinkList L)
{
    LinkList p;
    int len=0;
    p=L->next;
    while(p)
    {
        len++;
        p=p->next;
    }
    return len;
}

4.获得线性表中指定位次的数据元素

/*返回线性表中第i个元素,存储在e中*/
int GetElement(LinkList L,int i,ElementType *e)
{
    LinkList p;
    p=L->next;
    int num=1;
    while(p&&num<i)
    {
        p=p->next;
        num++;
    }
    if(!p||num>i)
    return ERROR;

    *e=p->data;

    return OK;
}

5.获得线性表中指定元素的位次

/*找到第一个与要求数据相符的元素,并返回其位次*/
int LocateElement(LinkList L,ElementType e)
{
    LinkList p;
    int num=0;
    p=L->next;
    while(p)
    {
        num++;
        if(p->data==e)
        return num;
        p=p->next;
    }

    return ERROR;
}

6.在线性表指定位次前插入元素

插入.jpg

/*在第i个元素之前插入数据元素e*/
int ListInsert(LinkList *L,int i,ElementType e)
{
    LinkList p,s;
    p=*L;
    int num=1;
    while(p&&num<i)
    {
        p=p->next;
        ++num;
    }
    if(!p||num>i)
    return ERROR;

    s=(LinkList)malloc(sizeof(Node));
    s->data=e;
    s->next=p->next;
    p->next=s;

    return OK;
}

7.删除线性表中指定位次的元素

删除.jpg

/*删除线性表中指定位次的元素*/
int ListDelete(LinkList *L,int i,ElementType *e)
{
    LinkList p,q;
    p=*L;
    int num=1;
    while(p&&num<i)
    {
        ++num;
        p=p->next;
    }
    if(!(p->next)||num>i)
    return ERROR;

    q=p->next;
    p->next=q->next;

    *e=q->data;

    free(q);

    return OK;
}

8.对线性表中的元素遍历输出

/*依次对线性表中每个元素遍历输出*/
int ListTraverse(LinkList L)
{
    LinkList p;
    p=L->next;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");

    return OK;
}

四、具体代码实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int ElementType;  /*存储数据的数据类型*/

typedef struct Node
{
    ElementType data;
    struct Node* next;
}Node;                        /*结点的定义*/

typedef struct Node* LinkList;/*线性表的定义*/

/*线性表的初始化*/
int InitList(LinkList *L)
{
    *L=(LinkList)malloc(sizeof(Node));/*产生头结点,并指向此头结点*/
    if(!(*L))
    return ERROR;

    (*L)->next=NULL;                  /*指针域为空*/

    return OK;
}

/*线性表的清空*/
int ClearList(LinkList *L)
{
    LinkList p,q;
    p=(*L)->next;

    while(p)
    {
        q=p->next;
        free(p);
        p=q;
    }
    (*L)->next=NULL;

    return OK;
}

/*获得线性表中元素的个数*/
int ListLength(LinkList L)
{
    LinkList p;
    int len=0;
    p=L->next;
    while(p)
    {
        len++;
        p=p->next;
    }
    return len;
}

/*返回线性表中第i个元素,存储在e中*/
int GetElement(LinkList L,int i,ElementType *e)
{
    LinkList p;
    p=L->next;
    int num=1;
    while(p&&num<i)
    {
        p=p->next;
        num++;
    }
    if(!p||num>i)
    return ERROR;

    *e=p->data;

    return OK;
}

/*找到第一个与要求数据相符的元素,并返回其位次*/
int LocateElement(LinkList L,ElementType e)
{
    LinkList p;
    int num=0;
    p=L->next;
    while(p)
    {
        num++;
        if(p->data==e)
        return num;
        p=p->next;
    }

    return ERROR;
}

/*在第i个元素之前插入数据元素e*/
int ListInsert(LinkList *L,int i,ElementType e)
{
    LinkList p,s;
    p=*L;
    int num=1;
    while(p&&num<i)
    {
        p=p->next;
        ++num;
    }
    if(!p||num>i)
    return ERROR;

    s=(LinkList)malloc(sizeof(Node));
    s->data=e;
    s->next=p->next;
    p->next=s;

    return OK;
}

/*删除线性表中指定位次的元素*/
int ListDelete(LinkList *L,int i,ElementType *e)
{
    LinkList p,q;
    p=*L;
    int num=1;
    while(p&&num<i)
    {
        ++num;
        p=p->next;
    }
    if(!(p->next)||num>i)
    return ERROR;

    q=p->next;
    p->next=q->next;

    *e=q->data;

    free(q);

    return OK;
}

/*依次对线性表中每个元素遍历输出*/
int ListTraverse(LinkList L)
{
    LinkList p;
    p=L->next;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");

    return OK;
}

void ListTest()
{
    LinkList L;
    ElementType e;

    int i,j,k;

    i=InitList(&L);
    printf("The length of linear table L after initialization is:Listlength=%d\n",ListLength(L));

    for(i=1;i<=6;i++)
    {
        j=ListInsert(&L,1,i);
    }
    printf("After inserting 1-6 into the header of L,data=:\n");
    ListTraverse(L);
    printf("Listlength=%d\n",ListLength(L));

    i=ClearList(&L);
    printf("After clearing the linear table, the length of the linear table is:%d\n",ListLength(L));

    for(i=1;i<11;i++)
    {
        j=ListInsert(&L,i,i);
    }
    printf("After inserting 1-10 into the tail of L,data=:\n");
    ListTraverse(L);
    printf("Listlength=%d\n",ListLength(L));

    GetElement(L,6,&e);
    printf("The 6th element in linear table L is:%d\n",e);

    printf("The number'3' is at :%d\n",LocateElement(L,3));

    i=ListDelete(&L,7,&e);
    printf("The seventh element deleted is %d\n",e);

    printf("The length of the list is %d\n",ListLength(L));

    i=ClearList(&L);
    printf("After clearing the linear table, the length of the linear table is:%d\n",ListLength(L));
}
int main()
{
    ListTest();
    return 0;
}

五、样例输出

The length of linear table L after initialization is:Listlength=0

After inserting 1-6 into the header of L,data=: 6 5 4 3 2 1

Listlength=6

After clearing the linear table, the length of the linear table is:0

After inserting 1-10 into the tail of L,data=: 1 2 3 4 5 6 7 8 9 10

Listlength=10

The 6th element in linear table L is:6

The number'3' is at :3

The seventh element deleted is 7

The length of the list is 9 After clearing the linear table, the length of the linear table is:0

六、写在最后

相对于线性表的顺序存储结构,链式存储结构在插入和删除功能上更育有优势,并且无需提前确定线性表的容量。因此,当线性表需要频繁的查找,很少进行插入和删除操作时,适用顺序存储结构;当线性表中的元素个数不定或很大时,使用链式存储结构。

这里是数据结构个人学习的笔记记录,如有问题欢迎指正说明。