3.栈和队列
2019-03-18 本文已影响0人
a9f9e33f60c3
1.栈
只能在一个位置上进行插入和删除的表,又称为LIFO(后进先出)表。
1.1栈的实现
任何实现表的方法都能实现栈,ArrayList和LinkedList均能实现栈。常用的两种实现栈的方法是:数组和链式结构
1.1.1栈的数组实现
1.用数组实现栈,存放数据
2.简单的push和pop方法实现
3.栈顶指针topOfStack以及栈的容量maxSize
public class MyStackByArray {
private Object [] theArray = null;//用数组存储
private int topOfStack = -1;//栈顶指针
private int maxSize = 0;//栈的容量
public MyStackByArray() {
this(10);//初始容量为10
}
public MyStackByArray(int initialSize) {
if(initialSize > 0) {
this.maxSize = initialSize;
theArray = new Object [maxSize];
}else {
System.out.println("栈容量不能小于等于0");
}
}
//压栈
public boolean push(Object o) {
//考虑栈溢出
if(topOfStack == maxSize - 1) {
System.out.println("栈溢出");
return false;
}
else{
theArray[++topOfStack] = o;
return true;
}
}
//出栈
public Object pop() {
if(topOfStack == -1) {
System.out.println("空栈");
return null;
}else {
return theArray[topOfStack--];
}
}
}
1.1.2栈的链表实现
1.节点类的定义
2.栈顶元素top
3.当前栈中元素size
4.pop和push方法的简单实现
public class MyStackByLink <T>{
//使用单链表实现,节点类
private class Node<T>{
private Node<T> next;
private T t;
public Node() {};
public Node(Node<T> next, T t) {
this.next = next;
this.t = t;
}
}
private Node<T> top;//栈顶元素
private int size = 0;//当前栈的大小
public MyStackByLink() {
top = null;
}
public int length() {
return size;
}
public boolean push(T t) {
//让top指向新创建的元素,并将该元素的next指向原来的top
top = new Node<T>(top,t);
size++;
return true;
}
public T pop() {
if(size == 0) {
System.out.println("栈为空");
return null;
}else {
//出栈并删除栈中该元素
Node<T> node = top;
top = top.next;
node.next = null;
size--;
return node.t;
}
}
1.2栈的应用
1.后缀表达式的计算
正常的数学表达式称为中缀表达式,例如a+bc+(de+f)*g;
a b c * + d e * f + g * + 则称为后缀表达式,又称为后缀或逆波兰记法。
计算方法:见到一个数就把他压入栈中,在遇到一个运算符时,该运算符就作用于从该栈中弹出的两个数上,再将所得结果压入栈中。
2.中缀到后缀的转换
当读到一个操作数的时候,立即把它放到输出中。操作符不立即输出,而是压入栈中。
压栈规则:
1)从栈中弹出栈元素直到发现优先级更低的元素为止,此操作完成后再压入栈中
2)左圆括号的优先级最高,除非处理右圆括号,否则不会从栈中弹出,左圆括号只弹出并不输出
3)读到输入末尾,将栈元素弹出直至变成空栈
2.队列
末端插入,首段删除,是一个FIFO(先进先出)表
2.1队列的实现
2.1.1队列的数组实现
1.队头front与队尾back
2.enqueue和dequeue的简单实现
3.当前队列中元素个数currentSize和队列容量maxSize
4.循环数组
public class MyQueueByArray {
private Object theArray [];//使用数组实现
private int front;//队头
private int back;//队尾
private int currentSize;//当前队列元素个数
private int maxSize;//队列最大元素个数
public MyQueueByArray() {};
public MyQueueByArray(int maxSize) {
this.maxSize = maxSize;
theArray = new Object [maxSize];
front = 0;
back = 0;
currentSize = 0;
}
public boolean enqueue(Object o) {
if(currentSize == maxSize) {
System.out.println("队列已满");
return false;
}
theArray[back] = o;
back = (back+1) % maxSize;
currentSize++;
return true;
}
public Object dequeue() {
if(currentSize == 0) {
System.out.println("队列为空");
return null;
}
Object obj = theArray[front];
front = (front+1) % maxSize;
currentSize--;
return obj;
}
2.1.2队列的链表实现
1.节点类
2.enqueue和dequeue的简单实现
public class MyQueueByLink<T> {
private class Node<T> {
private Node<T> next;
private T t;
public Node() {
}
public Node(Node<T> next, T t) {
this.next = next;
this.t = t;
}
}
private Node<T> front;
private Node<T> back;
private int maxSize;
private int currentSize;
public MyQueueByLink(int maxSize) {
front = null;
back = null;
this.maxSize = maxSize;
currentSize = 0;
}
public boolean enqueue(T t) {
if(maxSize == currentSize) {
System.out.println("队列已满");
return false;
}else if(currentSize == 0) {
front = new Node<T>(null,t);
back = front;
}
Node<T> newNode = new Node<T>(null,t);
back.next = newNode;
back = newNode;
currentSize++;
return true;
}
public T dequeue() {
if(currentSize == 0) {
System.out.println("队列为空");
return null;
}
Node<T> node = front;
front = front.next;
node.next = null;
currentSize--;
return node.t;
}
}
2.2队列的应用
排队论,例如卖票窗口