静态链表
可以用数组替代指针,来描述链表。让数组的每个元素由data和cursor(游标)两部分组成,其中cursor相当于链表的next指针,这种用数组描述的链表叫做静态链表,这种描述方法叫做游标实现法。
数组的第一个和最后一个元素做特殊处理,不存数据。
数组第一个元素的cursor存放第一个空闲结点的下标(备用链表的下标),数组的最后一个元素的cursor用来保存第一个插入元素的下标,初始时为0,相当于头结点作用。
图中和代码中为了便于理解用next表示了cursor
静态链表的初始状态:
插入一个元素:
再插入一个元素:
再插入一个元素30,此时静态链表中共有3个元素。删除位置为2的元素(即下标为1的元素):
代码如下:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define MAX_SIZE_SSL 10
#define OK 1
#define ERROR 0
typedef int ElemType;
/**
* 静态链表就是一个结构数组
* 数组第一个元素的next存放第一个空闲结点的下标(备用链表的下标)
* 数组的最后一个元素的next用来保存第一个插入元素的下标,初始时为0
*/
typedef struct{
ElemType data; //数据域
int next; // int cursor; 游标,如果为0表示无指向
}staticLinkList[MAX_SIZE_SSL];
void InitStaticLinkList(staticLinkList slList)
{
//每一个元素的next指向保存下一个元素的下标
for(int i = 0;i < MAX_SIZE_SSL;i++)
{
slList[i].next = i+1;
slList[i].data = -1; // 在输出的时候用来表示空闲结点
}
//将最后一个结点置空
slList[MAX_SIZE_SSL-1].next = 0;
//将备用链表的尾结点置为0
slList[MAX_SIZE_SSL-2].next = 0;
}
void OutPut(staticLinkList slList)
{
for(int i = 0;i < MAX_SIZE_SSL;i++)
{
cout << "i:" << i << "\tdata:" << slList[i].data << "\t\tnext:"<< slList[i].next << endl;
}
}
/*为静态链表分配一个单位的内存,即找到第一个空闲结点*/
int MallocSSL(staticLinkList slList)
{
//拿到第一个空闲结点下标(备用链表)
int cursor = slList[0].next;
if(cursor)
{
slList[0].next = slList[cursor].next;
}
return cursor;
}
/*回收原始数组中指定下标的空间*/
void FreeSSl(staticLinkList slList,int index)
{
//将下标为index的空闲结点回收到备用链表
slList[index].next = slList[0].next;//这个要释放的结点变为备用链表的第一个结点,原来第一个空闲结点的前缀结点
slList[index].data = -1;
slList[0].next = index;//更新第一个空闲结点
}
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;
}
int InsertStaticLinkList(staticLinkList slList,int pos,ElemType element)
{
if(pos < 1||pos > GetStaticLinkList(slList)+1)
return ERROR;
int cursor = MAX_SIZE_SSL - 1;//拿到第一个元素的下标
//分配内存
int newIndex = MallocSSL(slList);
if(newIndex)
{
slList[newIndex].data=element;
//找到newIndex的前缀结点 为pos位置前面的那个结点
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;
}
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;
FreeSSl(slList,delIndex);
return OK;
}
int main()
{
staticLinkList slList;
cout << "初始化静态链表(此时为空):\n";
InitStaticLinkList(slList);
OutPut(slList);
InsertStaticLinkList(slList,1,10);
cout << "插入一个元素10后:\n";
OutPut(slList);
InsertStaticLinkList(slList,2,20);
cout << "接着插入一个元素20后:\n";
OutPut(slList);
cout << "接着插入一个元素30后:\n";
InsertStaticLinkList(slList,3,30);
OutPut(slList);
cout << "删除位置为2的元素:\n";
DeleteStaticLinkList(slList,2);
OutPut(slList);
return 0;
}