1. 静态链表形式
静态链表存储:一般使用数组存储,一个数组元素就是一个存储结点
静态链表地址:下标作为地址
静态链表结点:链域、值域 链域存储后继结点的下标
2. 自由队列的建立和管理
#define N 1000 // 存储空间大小
#define NIL -1 // 空链域值
#define OVER -2 // 自由结点用完标记
typedef int element_type // 元素类型
typedef struct
{
element_type data; // 值域
int next; // 链域
}slist; // 结点类型名
slist a[N]; // 存储静态链表的数组
int av; // 自由队列首指针
void initial() // 自由队列初始化函数
{
int i;
int n = 6;
for(i = 0;i < n - 1;i ++) a[i] = i + 1; // 对链域初始化
a[n-1].next = NIL; // 最后一个是空链域
av = 0; // 自由队列首指针初值
}
int takeoff() // 分配结点函数
{
int i;
if(av == NIL) return OVER; //自由队列已空,返回溢出值
i = av; // 将首结点分配
av = a[av].next; // 首指针后移一位
return i; // 返回所分配的结点下标
}
void takeback(int p) // 回收结点函数
{
a[p].next = av; // 将p结点插在自由队列首结点之前
av = p; // 将首指针改为p结点
}
3. 静态链表插入和删除操作
3.1 插入
(1) 申请结点
int i = takeoff();
if(i == OVER) ···
else
{
a[p].data = x;
插入程序
}
(2) p插入在表头处
a[p].next = head;
head = p
(3) p插入在结点q右侧
a[p].next = a[q].next;
a[q].next = p;
3.2 删除
(1) 删除表头结点
p = head; // 获取要删除的结点下标
head = a[head].next; // 删除
takeback(p); // 回收结点(放到自由队列)
(2) 删除结点q的后继结点
p = a[q].next;
a[q].next = a[p].next;
takeback(p);
4. 静态链表单链域实现双向指针
名词解释
- 链表中每个结点的链域存放的是该结点的前驱结点和后继结点地址“按位异或”运算的结果值
- 按位异或运算^
f^f = 0
(f^s) ^ f = s
(f^s) ^ s = f - 链域和指针的关系
指针p1,p2,p3指向链表中三个相继结点
a[p2].link = p1 ^ p3
则
p1 = a[p2].link ^ p3
操作
- 插入操作
将q指向的结点插入在p2和p3之间
a[p].link = p2 ^ p3; // 建立新结点的链域
a[p2].link = (a[p2].link ^ p3) ^ q; // 建立新的连接 p2<->q
a[p3].link = (a[p3].link ^ p2) ^ q; // 建立新的连接 q<->p3
- 删除操作
删除p2指向结点
a[p1].link = (a[p1].link ^ p2) ^ p3; // 建立新的连接 p1<->p3
a[p3].link = (a[p3].link ^ p2) ^ p1;