通常称,栈和队列是限定插入和删除只能在表的“端点”进行的线性表。
栈和队列是两种操作受限的线性表,是两种常用的数据类型。
栈
- 栈的概念:栈是仅限制在表尾进行插入和删除操作的特 殊线性表,限制操作的表尾端称为“栈顶”, 另一 端称为“栈底”
- 栈是“后进先出”的线性表(LIFO)或 “先 进后出”的线性表(FILO)
3 .基本操作:
a)栈的置空操作:clear();
b)判空操作:isEmpty();
c)求长度:length();
d)取栈顶元素:peek();
e)入栈操作:push(x);
f)出栈操作:pop();
4 .栈的抽象数据类型的Java接口描述
public interface IStack{
public void clear();
public boolean isEmpty();
public int length();
public Object peek();
public void push(Object x) throws Exception;
public Object pop();
}
实现此接口的方法有两种: 1.顺序栈.2.链栈
- 顺序栈的基本操作实现
与顺序表一样,顺序栈也是用数组来实现的。由于入栈出栈操作都在栈顶进行,所以需要加上一个变量top来表示栈顶的元素的位置。top有两种定义方式,一种是将其设置为指向栈顶元素的下一个存储单元的位置,则空栈是top=0;另一种是将top设置为指向栈顶元素的存储位置,则空栈时,top=-1.我们一般使用前一种方式来表示栈顶(即top永远指向下一个压入栈的数据元素的存储位置)。
-
顺序栈类的描述
public class SqStack implements IStack {
private Object[] stackElem;
private int top;
//构造一个容量为maxSize的空栈
public SqStack (int maxSize) {
stackElem = new Object[maxSize];
top = 0;
}
// 栈置空
public void clear( ) {
top =0;
}
//栈判空
public boolean isEmpty(){
return top == 0;
}
//求栈中数据元素的个数
public int length(){
return top;
}
//取栈顶元素
public Object peek(){
if(!isEmpty())
return stackElem[top-1];
else
return null;
}
//入栈
public void push(Object x) throws Exception{
if(top==stackElem.length)
throw new Exception("栈已满");
else{
stackElem[top]=x;
top++;
}
}
//出栈
public Object pop(){
if(top == 0)
return null;
else {
retrun stackElem[--top];
}
}
//输出栈中的所有元素
public void display(){
for (int i =top-1;i>=0;i--){
System.out.print(stackElem[i].toString()+" ");
}
}
}
- 链栈的基本操作实现
栈的链式存储结构称为链栈,是运算受限的单链表,其插入和删除操作仅限制在链表的表头位置上进行,故链栈没有必要象单链表一样附加头结点,栈顶指针即为链表的头指针。
链栈类的描述
public class LinkStack implements IStack {
private Node top;
//置空
public void clear(){
top=null;
}
//判断链栈是否为空
public boolean isEmpty(){
return top == null;
}
//求链栈的长度
public int length(){
Node p = top;
int length = 0;
while(p!=null){
p = p.next;
length++;
}
return length;
}
//去栈顶元素并返回其值
public Object peek(){
if(top == null){
retrun null;
}
else {
retrun top.data;
}
}
//入栈
public void push(Object x){
Node p = new Node(x);
p.next = top;
top = p;
}
//出栈
public Object pop() {
if(top == null)
return null;
else{
Node p = top;
top = p.next;
return p.data;
}
}
//输出栈中的所有元素
public void display(){
Node p = top;
while(p!=null){
System.out.print(p.data+" ");
p=p.next;
}
}
}
队列
队列的概念:
(1) 队列是只允许在表的一端进行插入,而在表 的另一端进行删除操作的一种特殊线性表允许插入的一端称为“队尾”,允许删除的一端称为“队首”
(2) 栈是“先进先出”的线性表(FIFO)或“后进后出”的线性表(LILO)
2 .基本操作:a)栈的置空操作:clear();
b)判空操作:isEmpty();
c)求长度:length();
d)取对首元素:peek();
e)入队操作:offer(x);
f)出队操作:poll();
3.队列的抽象数据类型的Java接口描述
public interface IQueue{
public void clear();
public boolean isEmpty();
public int length();
public Object peek();
public void offer(Object x) throws Exception;
public Object poll();
}
实现此接口的方法有两种: 1.顺序队列 2.链式队列
顺序队列及其基本操作的实现
与顺序栈类似,在顺序队列的存储结构中,需要分配一块地址连续的存储区域来依次存放队列中从队首到队尾的所有元素。由于队列操作只能在当前队列的队尾进行而出队操作只能在当前队列的队首进行,所以需要加上变量front和rear来分别指示队首和队尾元素在数组中的位置,其初始值为0.在非空栈中,front指向队首元素,rear指向队尾元素的下一个存储位置。
循环顺序队列类的描述
public class CircleSqQueue implements IQueue {
private Object[] queueElem;
private int front;
private int rear;
//构造一个容量为maxSize的空循环队列函数
public CircleSqQueue (int maxSize) {
queueElem = new Object[maxSize];
front=rear = 0;
}
//队列置空
public void clear(){
front = rear=0;
}
//判断队列是否为空
public boolean isEmpty(){
retrun front == rear;
}
//求队列的长度
public int length(){
return (rear-front+queueElem.length)%queueElem.length;
}
//读取对首元素
public Object peek(){
if(front==rear)
return null;
else
retrun queueElem[front];
}
//入队
public void offer(Object x) throws Exception{
if((rear+1)%queueElem.length==front)
throw new Exception("队列已满");
else{
queueElem[rear] = x;
rear = (rear+1)%queueElem.length;
}
}
//出队
public Object poll(){
if(front == rear)
return null;
else{
Object t= queueElem[front];
front = (front+1)%queueElem.length;
return t;
}
}
//输出所有的数据元素
public void display(){
if(!isEmpty){
for(int i = front;i!=rear;i=(i+1)%queueElem.length)
System.out.print(queueElem[i].toString()+" ");
}
else{
System.out.println("队列为空");
}
}
}
链队列及其基本操作的实现
- 链队列:队列的链式存储结构称为链队列,其链式存储结构在此用不带头结点的单链表来实现.为了便于实现入队出队操作,需要引进两个指针front和rear来分别指向队首元素和队尾元素的结点。
2.链队列类的描述
public class LinkQueue implements IQueue {
private Node front;
private Node rear;
//置空队列
public void clear(){
front = rear = null;
}
//判断队列是否为空
public boolean isEmpty(){
return front == null;
}
//求队列的长度
public int length(){
Node p = front ;
int length = 0;
while (p!=null){
p=p.next;
length++;
}
return length;
}
//取队列的首元素
public Object peek(){
if(front!=null)
retrun front.data;
else
return null;
}
//入队
public void offer(Object x){
Node p = new Node(x);
if(front!=null){
rear.next = p;
rear = p;
}
else
front = rear = p;
}
//出队
public Object poll(){
if(front!=null){
Node p = front ;
front = front.next;
if(p==rear)
rear = null;
return p.data;
}
else
return null;
}
}
栈与队列的比较
- 栈与队列的相同点
- 1.都是线性结构,即数据元素之间具有“一对一”的逻辑关系。
- 2.插入操作都是限制在表尾进行。
- 3.都可在顺序存储结构和链式存储结构上实现。
- 4.在时间代价上,插入与删除操作都需常数时间;在空间上情况也相同。
- 5.多链栈和多链队列的管理模式可以相同。
- 栈与队列的不同点
- 删除数据元素操作的位置不同 。
- 两者的应用场合不相同 。
- 顺序栈可实现多栈空间共享,而顺序队列则不同 。
栈与队列的应用
栈的应用
例1. 分隔符匹配问题
例2. 大数加法问题
例3. 表达式求值问题
例4. 栈与递归问题队列的应用
- 编程实现求解的素数环问题
1220

被折叠的 条评论
为什么被折叠?



