含义:用数组描述的链表叫做静态链表。
静态链表实际上是为给没有指针的高级语言设计的一种实现单链表的方法
结构
typedef struct {
int data;//数据域
int cur;//游标
}COMPONENT,STATICLIST[MAXSIZE];
由data和cur两个数据域组成,数据域data用来存放数据,cur相当于单链表的指针域,数组的第一个元素和最后一个元素不存储数据,把未被使用的数组元素成为备用链表。数组的第一个元素,即下标为0的元素的cur存储备用链表的第一个节点的下标,而数组最后一个元素的cur则存放第一个数值的元素的下标。如下图所示:
1、创建静态链表
void creatList(STATICLIST space){
int i;
//设置静态链表的cur
for(i=0;i<MAXSIZE-1;i++)
space[i].cur=i+1;
//当静态链表为空时,最后一个元素的cur设置为零
space[MAXSIZE-1].cur=0;
}
先设置静态链表的cur(相当于单链表的指针域),当静态链表为空时,设置最后一个元素的cur为0。
2、初始化静态链表
void initList(STATICLIST space,int len){
int i;
//临时保存初始化的值
int temp;
//输入的数字超出范围时
if(len<1||len>MAXSIZE-2){
printf("初始化的个数已经超出了数组的长度,请重新输入len=");
scanf("%d",&len);
}
//输入初始化的值 ,下标为1的数组开始存储数据
for(i=1;i<=len;i++){
printf("请输入第%d个初始化的值:",i);
scanf("%d",&temp);
space[i].data=temp;
}
//初始化数值以后,将数组第一个元素的cur存放备用链表的第一个节点的下标
space[0].cur=len+1;
//数组最后一个元素的cur存放一个有数值的数组元素的下标
space[MAXSIZE-1].cur=1;
//将初始化后的最后一个保存有数值的元素的cur设置为0
space[len].cur=0;
}
3、链表长度
int listLength(STATICLIST space){
int j=0;
//相当于单链表的头节点,从这个下标开始遍历元素
int i=space[MAXSIZE-1].cur;
//直到数组元素的cur为零,当数组元素的cur为零,说明这就是保存有数值的最后一个元素
while(i){
i=space[i].cur;
j++;
}
return j;
}
4、遍历静态链表
void showList(STATICLIST space){
int i;
int temp;
//判断链表是否为空
if(space[MAXSIZE-1].cur ==0){
printf("链表为空!");
exit(-1);
}
//先获取开始遍历的下标
temp=space[MAXSIZE-1].cur;
for(i=1;i<=listLength(space);i++){
printf("%d ",space[temp].data);
//取得下一个数组元素的下标
temp=space[temp].cur;
}
printf("\n");
}
5、插入操作
一:模拟单链表的malloc()申请内存,即确定数组的哪一个元素来临时保存插入的数据
int molloc_list(STATICLIST space){
//保存备用链表的下标
int i;
//判断备用链表是否为满
if(space[0].cur<MAXSIZE-1){
//当前数组第一个元素的cur值
i=space[0].cur;
//让 space[0].cur等于下一个备用链表元素的cur
space[0].cur=space[i].cur;
}else{
printf("链表已满!");
}
return i;
}
二:插入
bool insert_list(STATICLIST space,int index,int e){
int i,j,k;
//k的值首先是最后一个元素的下标,以便找出 第index个元素前一个元素
k=MAXSIZE-1;
//判断插入的位置是否合理
//保证插入的位置在1~listLength(space)+1之间 ,包括在 slistLength(space)+1
if(index<1||index>listLength(space)+1){
printf("插入的范围不合理");
return false;
}
//得到备用链表的第一个元素的下标
j=molloc_list(space);
if(j){
//将插入的e保持存在备用链表的第一个元素里
space[j].data=e;
//遍历找到第index之前的位置
for(i=1;i<=index-1;i++)
k=space[k].cur;
//将备用链表的cur指向第index位置下一个元素的下标
space[j].cur=space[k].cur;
//将新元素的下标赋值给第index之前元素的cur
space[k].cur=j;
return true;
}
return false;
}
6、删除元素
一:模拟动态数组的 释放内存空间
void free_own(STATICLIST space,int k){
//把第一个元素的cur值赋给要删除的分量cur
space[k].cur=space[0].cur;
//把要删除的分量下标赋值给第一个元素的cur
space[0].cur=k;
}
二:删除元素
void delete_list(STATICLIST space,int index,int *val){
int j,k;
if(index<1||index>listLength(space)){
printf("插入的范围不合理");
}
k=MAXSIZE-1;
//循环遍历直到得到删除元素的前一个元素的下标
for(j=1;j<index-1;j++)
k=space[k].cur;
//得到删除元素的下标
j=space[k].cur;
*val=space[j].data;
//将删除元素的下一个元素接到删除元素的上一个元素上。
space[k].cur=space[j].cur;
//模式释放空间
free_own(space,j);
}
7、获取第index位置的数值
int getEle(STATICLIST space,int index){
//找到开始遍历的cur
int temp=space[MAXSIZE-1].cur;
int i;
// 找到第index前面的元素cur
for(i=1;i<index;i++){
temp=space[temp].cur;
}
//返回第index的值
return space[temp].data;
}
8、是否为空
bool is_empty(STATICLIST space){
if(space[MAXSIZE-1].cur==0)
return true;
else
return false;
}
9、是否为满
bool is_full(STATICLIST space){
if(space[0].cur==MAXSIZE-1)
return true;
else
return false;
}
10、冒泡排序
void sort_list(STATICLIST space){
int i,j;
int one,second;
int temp;
//获取开始遍历的下标
int oneCur=space[MAXSIZE-1].cur;
for(i=1,one=oneCur; i<space[0].cur; i++,one=space[one].cur){
for(j=i+1,second=space[one].cur; j<space[0].cur; j++,second=space[second].cur)
{
if(space[one].data>space[second].data){
temp=space[one].data;
space[one].data=space[second].data;
space[second].data=temp;
}
}
}
}
测试代码
int main()
{
int val;
//创建静态链表
STATICLIST space;
creatList(space);
//初始化
initList(space,6);
//输出链表
showList(space);
//插入元素
insert_list(space,7,999);
showList(space);
//找到第三位置的值
printf("第三位置的值%d\n",getEle(space,3));
//排序
printf("冒泡排序\n");
sort_list(space) ;
showList(space);
//删除元素
delete_list(space,1,&val);
printf("你删除的元素是%d\n",val);
delete_list(space,1,&val);
printf("你删除的元素是%d\n",val);
showList(space);
}
测试结果
源代码下载:http://download.youkuaiyun.com/detail/a_person_alone/9487965