本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、静态链表的定义
我们把用数组描述的链表叫做静态链表。 数组的元素都是由两个数据域组成,data和cur。数据域data存放数据元素,数据域cur相当于链表中的next指针,存放该元素的后继在数组中的下标。
/*静态链表存储结构的定义*/
#define MAXSIZE 1000
typedef struct
{
ElementType data;
int cur;
}Node,StaticLinkList[MAXSIZE];
二、静态链表的相关操作实现
1.静态链表的初始化
/*space[0].cur为头指针,“0”表示空指针*/
void InitList(StaticLinkList space)
{
int i;
for(i=0;i<MAXSIZE-1;i++)
space[i].cur=i+1;
space[MAXSIZE-1].cur=0;
}
2.获得空闲结点的下标
相当于手动实现一个malloc
/*返回分配的空闲结点的下标*/
int Malloc_SSL(StaticLinkList space)
{
int i=space[0].cur; /*数组的第一个元素的cur存的值即为第一个备用空闲的下标*/
if(space[0].cur)
space[0].cur=space[i].cur;
return i;
}
3.回收结点
手动实现free
/*回收空闲结点*/
void Free_SSL(StaticLinkList space,int k)
{
space[k].cur=space[0].cur;
space[0].cur=k;
}
4.获得静态链表中的元素个数
循环计数
/*返回静态链表中元素的个数*/
int ListLength(StaticLinkList L)
{
int i,num;
num=0;
i=L[MAXSIZE-1].cur; /*数组最后一个元素的游标(cur)为存放第一个有数值的元素的下标*/
while(i)
{
i=L[i].cur;
num++;
}
return num;
}
5.在静态链表中指定位置之前插入新的数据元素
/*在静态链表第i个元素之前插入指定数据元素e*/
int ListInsert(StaticLinkList L,int i,ElementType e)
{
int j,k,l;
k=MAXSIZE-1;
if(i<1||i>ListLength(L)+1)
return -1;
j=Malloc_SSL(L);
if(j)
{
L[j].data=e;
for(l=1;l<i;l++)
k=L[k].cur;
L[j].cur=L[k].cur;
L[k].cur=j;
return 0;
}
return -1;
}
6.删除静态链表中指定位置的元素
/*删除静态链表中第i个元素*/
int ListDelete(StaticLinkList L,int i)
{
int j,k;
if(i<1||i>ListLength(L))
return -1;
k=MAXSIZE-1;
for(j=1;j<i;j++)
k=L[k].cur;
j=L[k].cur;
L[k].cur=L[j].cur;
Free_SSL(L,j);
return 0;
}
7.遍历输出
/*遍历输出静态链表中的买个数据元素*/
int ListTraverse(StaticLinkList L)
{
int i,j;
i=L[MAXSIZE-1].cur;
j=0;
while(i)
{
printf("%c ",L[i].data);
i=L[i].cur;
j++;
}
return j;
printf("\n");
return 0;
}
三、具体代码实现
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef char ElementType;
#define MAXSIZE 1000
typedef struct
{
ElementType data;
int cur;
}Node,StaticLinkList[MAXSIZE];
/*space[0].cur为头指针,“0”表示空指针*/
void InitList(StaticLinkList space)
{
int i;
for(i=0;i<MAXSIZE-1;i++)
space[i].cur=i+1;
space[MAXSIZE-1].cur=0;
}
/*返回分配的空闲结点的下标*/
int Malloc_SSL(StaticLinkList space)
{
int i=space[0].cur; /*数组的第一个元素的cur存的值即为第一个备用空闲的下标*/
if(space[0].cur)
space[0].cur=space[i].cur;
return i;
}
/*回收空闲结点*/
void Free_SSL(StaticLinkList space,int k)
{
space[k].cur=space[0].cur;
space[0].cur=k;
}
/*返回静态链表中元素的个数*/
int ListLength(StaticLinkList L)
{
int i,num;
num=0;
i=L[MAXSIZE-1].cur; /*数组最后一个元素的游标(cur)为存放第一个有数值的元素的下标*/
while(i)
{
i=L[i].cur;
num++;
}
return num;
}
/*在静态链表第i个元素之前插入指定数据元素e*/
int ListInsert(StaticLinkList L,int i,ElementType e)
{
int j,k,l;
k=MAXSIZE-1;
if(i<1||i>ListLength(L)+1)
return -1;
j=Malloc_SSL(L);
if(j)
{
L[j].data=e;
for(l=1;l<i;l++)
k=L[k].cur;
L[j].cur=L[k].cur;
L[k].cur=j;
return 0;
}
return -1;
}
/*删除静态链表中第i个元素*/
int ListDelete(StaticLinkList L,int i)
{
int j,k;
if(i<1||i>ListLength(L))
return -1;
k=MAXSIZE-1;
for(j=1;j<i;j++)
k=L[k].cur;
j=L[k].cur;
L[k].cur=L[j].cur;
Free_SSL(L,j);
return 0;
}
/*遍历输出静态链表中的买个数据元素*/
int ListTraverse(StaticLinkList L)
{
int i,j;
i=L[MAXSIZE-1].cur;
j=0;
while(i)
{
printf("%c ",L[i].data);
i=L[i].cur;
j++;
}
return j;
printf("\n");
return 0;
}
void ListTest()
{
StaticLinkList L;
InitList(L);
printf("The length of the static linked list after initialization is:%d\n",ListLength(L));
ListInsert(L,1,'C');
ListInsert(L,1,'H');
ListInsert(L,1,'I');
ListInsert(L,1,'N');
ListInsert(L,1,'A');
printf("After inserting China into the header in turn:\n");
ListTraverse(L);
ListInsert(L,6,'e');
printf("\nAfter the last insertion of e:\n");
ListTraverse(L);
ListDelete(L,4);
printf("\nAfter deleting the fourth element:\n");
ListTraverse(L);
}
int main()
{
ListTest();
return 0;
}
四、样例输出
The length of the static linked list after initialization is:0
After inserting China into the header in turn: A N I H C
After the last insertion of e: A N I H C e
After deleting the fourth element: A N I C e
无、写在最后
静态链表改进了顺序存储结构中插入和删除需要移动大量元素的问题,但是也失去了随机存取的特性,并且没有解决表长难以确定的问题。
这里是数据结构个人学习的笔记记录,如有问题欢迎指正说明。