静态链表就是用数组来组织链表,用于没有指针的程序语言实现链表结构。较单链表复杂,需要自己实现malloc和free函数,还需要一个备用链来指出空闲结点。
/*
* 静态链表
* 适用于不设置指针的程序语言中实现链表结构,比如python
* 任然需要预先分配大量存储空间
* 优点:插入、删除不需要移动大量元素,仅需要修改整型游标,这里整型游标替代指针p
* 通常数组的第一个元素作为头指针
* 难点:相比较单链表,需要自己实现malloc, free函数,需要一个备用链表,备用链表头节点为L[0],游标cur=0,表示空
* */
#include <stdio.h>
#define MAXSIZE 1000
typedef bool Status;
typedef int ElemType;
typedef struct {
ElemType data;
int cur;
}component, SLinkList[MAXSIZE]; // L[0]是备用元素的头结点,链表的头结点怎么办?
int malloc(SLinkList &a) {
int i = a[0].cur; // L[0].cur始终指向可用节点的第一个的下标
if(i)
a[0].cur = a[i].cur;
return i;
}
int length(SLinkList& L, int head) {
return L[head].data-1; // 不计算头结点,复用头结点的数据域,不用迭代查找,效率更高
int i(L[head].cur);
int count(0);
while (L[i].cur!=0) {
i = L[i].cur;
count++;
}
return count;
}
void free(SLinkList &L, int k) {
L[k].cur = L[0].cur; // k节点链接可用节点的头结点
L[0].cur = k;
}
void InitList(SLinkList &a) {
for(int i=0; i<MAXSIZE; i++)
a[i].cur = i+1;
a[MAXSIZE-1].cur = 0; // 尾节点cur=0,表示空指针
}
void print(SLinkList& a, int head) {
printf("static link list size: %d\n", length(a, head));
int i(a[head].cur); // 不打印头结点
while (a[i].cur != 0) {
printf("%d\t", a[i].data);
i = a[i].cur;
}
printf("\n\n");
}
/*
* 建表
* 在初始化之后执行
* */
Status create(SLinkList &sll, ElemType* tc, int size, int &S) {
S = malloc(sll);
sll[S].data = 0;
int r = S;
for(int i=0; i<=size; i++) {
int j = malloc(sll);
sll[j].data = tc[i];
sll[r].cur = j;
r = j;
sll[S].data++;
// printf("head=%d, value=%d, length=%d\n", S, tc[i], length(sll, S));
}
sll[r].cur = 0;
}
Status insert(SLinkList& a, int head, int pos, ElemType val) {
if(pos<1 || pos>length(a, head))
return false;
// 获取插入元素的位置下标 i
int i(head);
int count(1);
while (a[i].cur!=0) {
if(count == pos)
break;
i = a[i].cur;
count++;
}
// 建链
int newNode = malloc(a);
a[newNode].data = val;
a[newNode].cur = a[i].cur; //
a[i].cur = newNode;
a[head].data++; // 静态链表长度+1
return true;
}
Status ListDelete(SLinkList &a, int head, int pos, ElemType &val) {
if(pos<1 || pos>length(a, head))
return false;
int i(head);
int count(1);
while(a[i].cur!=0) {
if(count++ == pos)
break;
i = a[i].cur;
}
int j = a[i].cur;
a[i].cur = a[j].cur;
val = a[j].data;
free(a, j);
return true;
}
ElemType getElem(SLinkList& a, int head, int pos) {
if(pos<1 || pos>length(a, head))
return -1;
// 获取pos前一个元素的下标
int i(head);
int count(1);
while (a[i].cur!=0) {
if(count++ == pos)
break;
i = a[i].cur;
}
int target = a[i].cur;
return a[target].data;
}
Status modify(SLinkList& a, int head, int pos, ElemType val) {
if(pos<1 || pos>length(a, head))
return false;
int i(head);
int count(1);
while (a[i].cur!=0) {
if(count++ == pos)
break;
i = a[i].cur;
}
int j = a[i].cur;
a[j].data = val;
return true;
}
/*
* 返回第一个等于val的元素属于链表的第几个
*
* */
int search(SLinkList& a, int head, ElemType val) {
int i(head);
int count(0);
while (a[i].cur!=0) {
i = a[i].cur;
count++;
if(a[i].data == val)
return count;
}
return -1;
}
void difference(SLinkList& space, int &S) {
InitList(space);
S = malloc(space); // S是静态链表的头结点
int r = S; // r是静态链表尾节点的下标,建表初始,该下标指向头结点
int m=3, n=4; // A,B 的元素个数
for(int j=1; j<=m; ++j) {
int i = malloc(space);
space[i].data = j*2;
// 尾插法
space[r].cur = i; // 指向新结点
r = i; // 更新下标
}
space[r].cur = 0; // 尾节点的指针尾空
for(int j=1; j<=n; ++j) {
}
}
int main() {
ElemType testCase[] = {
6501,6828,6963,7036,7422,7674,8146,8468,8704,8717,9170,9359,9719,9895,9896,9913,9962,154,293,334,492,1323,
1479,1539,1727,1870,1943,2383,2392,2996,3282,3812,3903,4465,4605,4665,4772,4828,5142,5437,5448,5668,5706,
5725,6300,6335
};
int size = sizeof(testCase) / sizeof(ElemType);
printf("size=%d\n", size);
SLinkList a; // 创建静态链表
InitList(a);
int head;
create(a, testCase, size, head);
print(a, head);
insert(a, head, 1, 100);
print(a, head);
insert(a, head, 3, 200);
print(a, head);
insert(a, head, 48, -200);
print(a, head);
for(int i=0; i<10; i++) {
insert(a, head, i*2, -i*3);
print(a, head);
}
ElemType e;
ListDelete(a, head, 1, e);
printf("e=%d\n", e);
print(a, head);
ListDelete(a, head, 5, e);
printf("e=%d\n", e);
print(a, head);
int pos=1;
printf("get element-%d=%d\n", pos, getElem(a, head, pos));
pos = 3;
printf("get element-%d=%d\n", pos, getElem(a, head, pos));
modify(a, head, 1, 111);
print(a, head);
modify(a, head, 3, 333);
print(a, head);
printf("search index=%d\n", search(a, head, 333));
printf("search index=%d\n", search(a, head, 6828));
return 0;
}