静态链表就是把链表与数组结合起来,也就是用数组描述的链表,即称为静态链表。
但是在java和c中这种数据结构是不需要的,它主要用于没有指针的编程语言。
与线性表与数组的区别
首先同样是定义一个头文件在头文件中定义函数,宏和全局变量
#ifndef STATICLINKLIST_H_INCLUDED
#define STATICLINKLIST_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE_SSL 10
#define OK 1
#define ERROR 0
//定义数据元素
typedef struct{
int id;
char * name;
}ElementType;
/** 静态链表-就是一个结构数组 */
typedef struct{
ElementType data; //数据域
int next; //int cursor; 游标,如果为0表示无指向
}StaticLinkList[MAX_SIZE_SSL];
/** 初始化链表 */
void InitStaticLinkList(StaticLinkList slList);
/** 向指定位置插入元素 */
int InsertStaticLinkList(StaticLinkList slList, int pos, ElementType element);
/** 为静态链表分配一个空间的内存,返回ERROR表示分配失败 */
int mallocSSL(StaticLinkList slList);
/** 删除链表中指定位置的元素 */
int DeleteStaticLinkList(StaticLinkList slList, int pos);
/** 回收原始数组中指定下标的空间 */
void FreeStaticLinkList(StaticLinkList slList, int index);
/** 获得静态链表的长度 */
int GetStaticLinkList(StaticLinkList slList);
void PrintStaticLinkList(StaticLinkList slList);
#endif // STATICLINKLIST_H_INCLUDED
下面在.c中对静态链表进行操作
插入的过程相当于数组的位置没有改变但是改变了游标的指向,使之排列起来
#include "StaticLinkList.h"
/** 初始化链表 */
void InitStaticLinkList(StaticLinkList slList)
{
for(int i = 0; i < MAX_SIZE_SSL; i++)
{
slList[i].data.id = -1;
slList[i].data.name = NULL;
slList[i].next = i + 1;
}
//将最后一个结点置空
slList[MAX_SIZE_SSL - 1].next = 0;
//将备用链表的尾结点置为空
slList[MAX_SIZE_SSL - 2].next = 0;
}
/** 删除链表中指定位置的元素 */
int DeleteStaticLinkList(StaticLinkList slList, int pos){
if(pos < 1 || pos > GetStaticLinkList(slList)){
return ERROR;
}
int cursor = MAX_SIZE_SSL - 1;
//通过循环找到要删除位置的前缀结点
for(int i = 1; i <= pos - 1; i++){
cursor = slList[cursor].next;
}
int delIndex = slList[cursor].next;
slList[cursor].next = slList[delIndex].next;
//释放空间
FreeStaticLinkList(slList, delIndex);
return OK;
}
/** 回收原始数组中指定下标的空间 */
void FreeStaticLinkList(StaticLinkList slList, int index){
//将下标为index的空闲结点回收到备用链表
slList[index].next = slList[0].next;
//0号元素的next结点指向备用链表的第一个结点,表示index结点空闲
slList[0].next = index;
}
/** 向指定位置插入元素 */
int InsertStaticLinkList(StaticLinkList slList, int pos, ElementType element){
if(pos < 1 || pos > GetStaticLinkList(slList) + 1){
return ERROR;
}
int cursor = MAX_SIZE_SSL - 1; //拿到第一个元素的下标
//需要判断cursor的范围是否合法
//分配内存
int newIndex = mallocSSL(slList);
if(newIndex){
slList[newIndex].data = element;
//找到newIndex的前缀结点
for(int i = 1; i <= pos - 1; i++){
cursor = slList[cursor].next;
}
slList[newIndex].next = slList[cursor].next;
slList[cursor].next = newIndex;
return OK;
}
return ERROR;
}
/** 为静态链表分配一个空间的内存,返回ERROR表示分配失败 */
int mallocSSL(StaticLinkList slList){
//拿到第一个空闲结点下标(备用链表)下标
int cursor = slList[0].next;
if(cursor){
slList[0].next = slList[cursor].next;
}
return cursor;
}
/** 获得静态链表的长度 */
int GetStaticLinkList(StaticLinkList slList){
int count = 0;
int cursor = slList[MAX_SIZE_SSL - 1].next;
while(cursor){
//p = p->next
cursor = slList[cursor].next;
count++;
}
return count;
}
void PrintStaticLinkList(StaticLinkList slList){
for(int i = 0; i < MAX_SIZE_SSL; i++)
{
printf("i:%d\tnext:%d\tid:%d\tname:%s\n", i, slList[i].next, slList[i].data.id, slList[i].data.name);
}
}