栈:
用数组S[1..n]实现一个至少有n个元素的栈。数组S属性top[S]指向最近插入的元素。由S实现的栈包含S[1..top[S]],
其中S[1]是栈底,S[top[S]]是栈顶元素。top[S]=0时,栈是空栈。判断一个栈是否为空,用查询操作STACK-EMPTY。
尝试对空栈作弹出操作,称为栈下溢,如果top[S]超过n,则称为栈上溢。
STACK-EMPTY(S)
if top[S] == 0
then return true;
else return false;
PUSH(S, x)
top[S] <- top[S] + 1;
S[top[S]] = x;
POP(S)
if STACK-EMPTY(S)
then error "underflow"
else top[S] <- top[S] - 1;
return S[top[S]+1]
--------------------------------------------------
队列:
把作用于队列上的INSERT操作称为入列(ENQUEUE),作用于队列上的DELETE操作称为出对(DEQUEUE)。用数组Q[1..n]实现至少包含n-1个元素的
队列的方法。队列具有属性head[Q],指向队列的头,另一个属性为tail[Q], 指向元素将会被插入的地方。队列中个元素的位置为head[Q],
head[Q]+1, ... , tail[Q] - 1.在最后的位置卷绕,队列中n个元素拍成环形,位置1在位置n之后。head[Q] = tail[Q],队列为空。
一开始head[Q] = tail[Q] = 1,从空队列中进行删除操作,导致队列下溢;当head[Q] = tail[Q] + 1, 队列为满,如果试图向队列
插入元素,导致队列上溢。
ENQUEUE(Q, x)
if head[Q] == tail[Q] + 1
then error "upflow"
else then tail[Q] = x;
if tail[Q] = length[Q]
then tail[Q] = 1
else tail[Q] = tail[Q] + 1
DEQUEUE(Q)
if head[Q] == tail[Q]
then error "underflow"
else then
x = Q[head[Q]]
if head[Q] = length[Q]
then head[Q] = 1
else head[Q] = head[Q] + 1
return x
T=0 T=1 T=2 T=3 T=2 T=3 T=2
------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------
| | | | | | 4| | | | | | 4| 1| | | | | 4| 1| 3| | | | 4| 1| | | | | 4| 1| 8| | | | 4| 1| | | | |
------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------
h h h h h h h
------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------
| | | | | | 4| | | | | | 4| 1| | | | | 4| 1| 3| | | | |1 |3 | | | | | 1| 3| 8| | | | | 3| 8| | |
------------------ ------------------ ------------------ ------------------ ------------------ ------------------ ------------------
t t t t t t t
链表:
对象按线性顺序排序,数组的线性顺序由下标决定,链表中顺序由个对象中的指针决定,能简单而灵活表示动态集合。
双链表L中每个元素都是一个对象。每个对象由关键字域和两个指针域:next和prev。对象可能包含其他卫星数据。对于链表中某个元素x,
next[x]指向链表中x的后续元素,而prev[x]指向链表中x的前驱元素。如果prev[x] = NIL,则x没有前驱,则是链表的第一个元素,就是head.
如果next[x] = NIL,则元素x没有后继,它是链表中最后一个元素,即tail。属性head[L]指向表的第一个元素。如果head[L]=NIL,则链表为空。
LIST-SEARCH(L, k)
x = head[L]
while x != NIL and key[x] != k
do x = next[x]
return x
LIST-INSERT(L, x) //将x插入到链表的前端
next[x] = head[L]
if head[L] != NIL
then prev[next[x]] = x
head[L] = x
next[x] = NIL
LIST-DELETE(L, x)
if prev[x] != NIL
then next[prev[x]] = next[x]
else head[L] = next[x]
if next[x] != NIL
then prev[next[x]] = prev[x]
哨兵:如果忽视表头和表尾的边界条件,
LIST-DELETE(L, x)
next[prev[x]] = next[x];
prev[next[x]] = prev[x];
假设有链表L和一个对象nil[L],nil[L]表示NIL,也包含和其他元素一样的的各个域,这样将一般双向链表
变成一个带哨兵的环形双向链表,哨兵元素nil[L]介于头和尾之间。 next[nil[L]]指向表头,这样可以去掉
head[L]属性,把对它的引用换成next[nil[L]]的引用。一个空链表只含哨兵元素,因为next[nil[L]]和prev[nil[L]]
都可以被置成nil[L]
LIST-SEARCH-V1(L, k)
x = next[nil[x]]
while x != nil[L] and key[x] != k
x = next[x]
return x
LIST-INSERT-V1(L, x)
next[x] = next[nil[x]]
prev[next[nil[L]]] = x
next[nil[x]] = x
prev[x] = nil[L]