静态链表
应用场景:
1.不支持指针的低级语言
2.数据元素数量固定不变的常量(例如操作系统中的文件分配表FAT)
优点:增删操作无需移动大量元素
缺点:不能随机存取,只能从头结点开始依次往后查找,容量固定不变。
//静态链表:用数组的方式实现的链表
//设数组下标为0的位置为头结点
#define MaxSize 20
#include<stdio.h>
typedef struct{
int data;
int next;
}SLinkList[MaxSize];
/*等价于
struct Node{
int data;
int next;
};
typedef struct Node SLinkList[MaxSize];
//可将SLinkList定义为一个长度为MaxSize的Node型数组
*/
//初始化为-2,静态链表以next值为-1为结束的标志
bool InitSLinkList(SLinkList &a){
a[0].next=-1;//初始化时,头结点的next位-1为结束的标志
for(int i=1;i<MaxSize;i++){
a[i].next=-2;
}
return true;
}
bool PrintSLinkList(SLinkList a){
int i=a[0].next;//找到第一个元素的下标
if(i==-1){
printf("数组为空\n");
return false;
}
printf("List is:");
do{
printf("%d ",a[i].data);
i=a[i].next;
//printf("\ni= %d\n",i);
}while(i != -1);
printf("\n");
return true;
}
//插入位序为i的结点
/*
1.找到一个空节点,存入数据元素
2.从头结点出发找到位序为i-1的结点
3.修改i-1结点的next 和插入的新结点的next
*/
bool InsertElem(SLinkList &a, int i,int e){
int j=0;//记录位序,找到第i-1个元素,将e插入其后
int vacant;//记录空位置
for(vacant=1;a[vacant].next!=-2;vacant++);
a[vacant].data=e;//找到一个空位置,存入新值
if(vacant >= MaxSize){
printf("数组已满\n");
return false;
}
//找到位序为i-1的位置
for(int k=0;a[k].next !=-1 && j<i-1;){
k=a[k].next;
j++;
}
if(j !=i-1){//位序超出数组长度
printf("非法位序\n");
return false;
}
//修改i-1结点的next 和插入的新结点的next
a[vacant].next = a[j].next;
a[j].next=vacant;
return true;
}
//删除位序为i的节点
/*1.从头结点出发找到前驱节点
2.修改前驱结点的游标
3.被删除结点的next设为-2,表示空闲下来了
*/
bool DeleteElem(SLinkList &a,int i){
if(i<1){
printf("非法位序\n");
return false;
}
int j=0;//找到第i-1个结点
for(int k=0;a[k].next!=-1 && j<i-1;){
k=a[k].next;
j++;
}
if(a[i].next == -1){//要删除的是最后一个结点
a[j].next=-1;
a[i].next=-2;
return true;
}
a[j].next=a[i].next;//删除的不是最后一个结点
a[i].next=-2;
return true;
}
int main(){
SLinkList a;//a为一个静态数组
InitSLinkList(a);
for(int i=1;i<5;i++){
InsertElem(a,i,i);
}
PrintSLinkList(a);
DeleteElem(a,3);
PrintSLinkList(a);
InsertElem(a,3,3);
PrintSLinkList(a);
InsertElem(a,8,30);
PrintSLinkList(a);
}