栈
一、栈的特性:先进后出
二、中缀表达式如何转后缀表达式?
1.方法x = A + B*(C-(D+F))/E
(1)将每一步的运算给它加上括号
(2)将每一步的运算符号移动到该运算的括号外
(3)去掉括号,得出结果
2.如何运算?(编译原理)
将所得到的结果依次入栈,若是操作数的话入栈,若是运算符,则取出栈顶的元素分别放到运算符的右侧和左侧,再将计算后的结果放入栈中。
三、栈的代码实现
public class TestStack {
private int[] elem;
private int usedSize;
public TestStack() {
this.elem = new int[10];
}
public boolean isFull() {
return this.usedSize == this.elem.length;
}
//进栈
public int push(int item) {
if (isFull()) {
/*throw new RuntimeException("栈为满");*/
this.usedSize = this.usedSize * 10;//扩容
}
elem[this.usedSize] = item;
this.usedSize++;
return elem[this.usedSize-1];
}
public boolean empty() {
return this.usedSize == 0;
}
//弹出栈顶元素,并删除
public int pop() {
if (empty()) {
throw new RuntimeException("栈为空");
}
this.usedSize--;
return elem[this.usedSize];
}
//拿到栈顶元素,不是删除
public int peek() {
if (empty()) {
throw new RuntimeException("栈为空");
}
return elem[this.usedSize-1];
}
}
四、如果用链表实现栈,入栈是头插好还是尾插好?
头插:
入栈:O(1)
出栈: O(1)
尾插:需要遍历链表,找它的尾结点。
入栈:O(n)
出栈: O(n)
队列
一、特性:先进先出(队尾进队头出)
二、使用双向链表实现队列
class Node {
public int value;
public Node next;
public Node(int value) {
this.value = value;
}
}
public class TestQueue {
public Node first;
public Node last;
public boolean offer(int value) {
Node node = new Node(value);
if (this.first == null) {
this.first = node;
this.last = node;
} else {
this.last.next = node;
this.last = node;
}
return true;
}
public boolean isEmpty() {
if (this.last == null && this.first == null) {
return true;
}
return false;
}
public int poll() throws RuntimeException{
if (isEmpty()) {
throw new RuntimeException("队列为空!");
} else {
int ret = this.first.value;
this.first = this.first.next;
return ret;
}
}
public int peek() throws RuntimeException{
if (isEmpty()) {
throw new RuntimeException("队列为空!");
} else {
int ret = this.first.value;
return ret;
}
}
}
三、循环队列
1.判空:this.front ==this.rear
2.判满:(this.rear+1)%this.elem.length == this.front
四、队列中的add()方法和offer()方法的区别:
两者都是往队列尾部插入元素,不同的时候,当超出队列界限的时候,add()方法是抛出异常让你处理,而offer()方法是直接返回false