本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、线性表链式存储结构
无需提前确定存储空间的容量,可以用一组任意的存储单元存储线性表的数据元素。
二、链式存储的定义
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.在线性表指定位次前插入元素
/*在第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.删除线性表中指定位次的元素
/*删除线性表中指定位次的元素*/
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
六、写在最后
相对于线性表的顺序存储结构,链式存储结构在插入和删除功能上更育有优势,并且无需提前确定线性表的容量。因此,当线性表需要频繁的查找,很少进行插入和删除操作时,适用顺序存储结构;当线性表中的元素个数不定或很大时,使用链式存储结构。
这里是数据结构个人学习的笔记记录,如有问题欢迎指正说明。