一
静态链表听说是前人为了模仿指针而想出来的,数组本来的下标和游标在程序的对应关系变化着实让人觉得惊叹。
二
规定:
1、在静态链表中第一个和最后一个元素,它们的data中不存放数据
2、通常将未使用的数组元素称为备用链表
3、数组的一个元素(下标为0的元素)的cur存放备用链表的第一个结点的下标
4、数组的最后一个元素(下标为MAXSIZE-1的元素)的cur存放第一个有数值的元素的下标,相当于单链表的头结点
静态链表需要实现c的malloc和free函数,来进行结点的申请和释放操作
//分配结点函数
int Malloc_SL(SLinkList space)
{
int i = space[0].cur;//space[0].cur存的都是链表元素下一个紧接的空位置
if(space[0].cur)
space[0].cur = space[i].cur;//为space[0].cur存入下一个空结点的数组下标
return i;
}
//回收结点
void Free_SL(SLinkList space, int k)
{
space[k].cur = space[0].cur;
space[0].cur = k;
//将要删除结点的下标赋值给space[0].cur,后面通过控制输出来实现结点的释放
}
insert操作
delete操作
这里结点并非真正的销毁了,而是可以说“隐藏”了,仍然可以通过数组下标访问到。
三
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#define OK 0
#define ERROR 0
#define MAXSIZE 50
typedef int ElemType;
typedef int Status;
typedef struct
{
ElemType data;
int cur; //相当于单链表的指针
} Component, SLinkList[MAXSIZE];
Status visit(ElemType c)
{
printf("%c ",c);
return OK;
}
Status ListTraverse(SLinkList space)
{
int j=0;
int i=space[MAXSIZE-1].cur;
while(i)
{
visit(space[i].data);
i=space[i].cur;
j++;
}
return j;
printf("\n");
return OK;
}
// 初始化静态链表
Status InitList(SLinkList space)
{
int i;
for(i=0; i<MAXSIZE-1; i++)
//将所有空结点都连接起来
space[i].cur = i+1;
space[MAXSIZE-1].cur = 0;
return OK;
}
//分配结点函数
int Malloc_SL(SLinkList space)
{
int i = space[0].cur;
if(space[0].cur)
space[0].cur = space[i].cur;
return i;
}
//回收结点
void Free_SL(SLinkList space, int k)
{
space[k].cur = space[0].cur;
space[0].cur = k;
//将要删除结点的下标赋值给space[0].cur,后面通过控制输出来实现结点的释放
}
//静态链表的长度
int ListLength(SLinkList space)
{
// int i=0,j=0;
// while(space[i].cur==0) //想着直接判断游标为0就链表就循环完了,谁知连起始点都没找到
// {
// i = space[i].cur;
// ++j;
// }
int i= space[MAXSIZE-1].cur;//从头节点开始
int j=0;
while(i)
{
i=space[i].cur;
j++;
}
return j;
}
//插入新的数据元素e
Status ListInsert(SLinkList space, int i, ElemType e)
{
int j, k, l;
k = MAXSIZE - 1; //数组的最后一元素相当于头结点
if (i < 1 || i > ListLength(space) + 1)
return ERROR;
j = Malloc_SL(space);
if (j)
{
space[j].data = e; //插入数据
//以下操作用于改变游标
for(l = 1; l <= i - 1; l++)//遍历到要插入元素位置的前一个位置
k = space[k].cur;
space[j].cur = space[k].cur;
space[k].cur = j;
return OK;
}
return ERROR;
}
//删除在L中第i个数据元素
Status ListDelete(SLinkList space, int i)
{
int j, k;
if (i < 1 || i > ListLength(space))
return ERROR;
k = MAXSIZE - 1;
for (j = 1; j <= i - 1; j++)//循环至删除位置的前一个元素位置
k = space[k].cur;
j = space[k].cur;
space[k].cur = space[j].cur;//将删除结点与后一结点游标交换
Free_SL(space, j);
return OK;
}
int main(void)
{
SLinkList L;
Status i;
i=InitList(L);
printf("初始化L后:L.length=%d\n",ListLength(L));
i=ListInsert(L,1,'A');
i=ListInsert(L,2,'B');
i=ListInsert(L,3,'D');
i=ListInsert(L,4,'E');
i=ListInsert(L,5,'F');
printf("\n在L的表头依次插入FEDBA后:\nL.data=");
ListTraverse(L);
i=ListInsert(L,3,'C');
printf("\n在L的“B”与“D”之间插入“C”后:\nL.data=");
ListTraverse(L);
i=ListDelete(L,1);
printf("\n在L的删除“A”后:\nL.data=");
ListTraverse(L);
printf("\n表长:L.length=%d\n",ListLength(L));
//A删除之后B为位置1
i=ListDelete(L,2);
printf("\n在L的删除“C”后:\nL.data=");
ListTraverse(L);
printf("\n表长:L.length=%d\n",ListLength(L));
printf("\n");
return 0;
}