栈和队列
栈
栈(stack),是插入和删除遵循后进先出(last-in first out,LIFO)原则的对象的容器。抽象的看,栈S是支持下面两种方法的容器:
- push(o):在栈的顶部插入对象o。O(1)
- pop(o): 将栈顶对象从栈中删除并返回该对象;如果栈为空,则发送错误。O(1)
基于数组的实现
//初始化
S[N]
t ← -1 //指向栈顶元素的索引,-1时栈空,N-1时栈满。
//进栈
push(o):
if t + 1 = N then
return 发生栈满错误
t ← t + 1
S[t] ← o
//出栈
pop(o):
if t < 0 then
return 发生栈空错误
e = S[t]
S[t] = null
t ← t -1
return e
缺点:必须假定栈最终大小的固定上界。
基于链表的实现
应用
① 方法栈(method stack):用于跟踪执行过程中被调用的局部变量和方法的其他重要信息。
② 递归(recursion):允许一个方法将自身作为子程序调用。
队列
队列(queue),是根据先进先出(first-in first-out,FIFO)原则进行插入和删除的对象的容器。抽象的看,队列Q是支持下面两种方法的容器:
- enqueuer(o):在队列尾部插入对象。O(1)
- dequeuer(o):删除并返回队列头部的对象;如果队列为空,则发生错误。O(1)
基于数组的实现
//初始化
Q[N] //循环数组
f ← 0 //队头(front)元素的索引,下一个要出队的索引
r ← 0 //队尾(rear)元素的索引,下一个可入队的索引,f=r队空,队满
//入队
enqueuer(o):
if (N - f + r) mod N = N -1 then
return 发生队满错误
Q[r] ← o;
r ← (r + 1) mod N
return
//出队
if f = r then
return 发生队空错误
e ← Q[f]
Q[f] ← null
f ← (f + 1) mod N
return e
缺点:必须假定队列最终大小的固定上界。
应用
① 流式传输
② 请求队列