一 栈
二 队列
三 链表
1. 静态链表解题步骤
- 定义静态链表
struct node{
int address;
int data;
int next;
int XXX; // 结点的某个性质
};
- 程序开始前对链表初始化。一般来说需要对链表的XXX属性进行初始化,将其定义为正常情况达不到的数字。
for (int i = 0; i < maxn; i++) {
Node[i].XXX = maxn;
}
- 根据给出的首地址遍历得到整条链表。同时对性质XXX 进行标记。比如设置XXX为有效结点,令XXX=true。
int p = begin, count = 0;
while (p != -1) {
XXX = 1;
count++;
p = Node[p].next;
}
-
由于静态链表是使用地址直接映射(hash)的方式,这就会使得数组下标的不连续,而很多时候题目给出的结点并不都是有效结点(即可能存在无效结点)。为了能够可控地访问有效结点,一般都需要对数组进行排序以把有效结点移动到数组左端,这样就可以用第三步的count访问它们。
既然要把有效结点移到前面,此时就可以使用之前定义的XXX来帮忙。在步骤2中XXX需要被初始化为比正常结点的XXX取值要小的数值。于是在写sort函数时就可以根据XXX从大到小排序,就可以把有效结点移动到数组左端。 -
一般来说,题目可能有额外要求。因此cmp函数需要有第二级排序。例如:如果题目中要求需要把链表按结点顺序排序,就需要在cmp函数中建立第二级排序。即在cmp函数的两个参数节点中有无效结点时按XXX从大到小排序,而当两个几点都是有效节点时按照结点在链表中的位置从小到大排序。
bool cmp(node a, node b) {
if (a.XXX == -1 || b.XXX == -1) {
return a.XXX > b.XXX; //只要有一个无效结点,就放到数组后面
} else {
//第二级排序
}
}
2. 例题
- A1052 注意全是无效结点的情况(测试点5) 应当输出 0 -1
- A1074 重点