栈(Stack)
概念
栈(Stack)继承于Vector,底层是一个数组 栈是先进后出的数据结构
1、判断进出栈的顺序
答案是C
2、计算机通过栈进行计算
中缀表达式——>后缀表达式 (加括号,移符号,去括号)
把数字放入栈中 遇到算术运算符,从栈中提出两个数字运算,先右后左(针对 - 和 /) 运算结果放入栈中 如此循环,直到栈为空结束,得到计算结果
XABCD-*E/+=
使用栈
Stack<Integer> stack = new Stack<>();
栈常用的方法 | |
---|
public E push(E item) | 将一个元素入栈 | public synchronized E pop() | 删除栈顶元素并返回此元素 | public synchronized E peek() | 得到栈顶元素 | public boolean empty() | 判断栈是否为空 | public synchronized int search(Object o) | 查找指定元素,返回[ size()-下标(下标是数组下标)],即返回元素的排名(栈顶元素为1,向下元素依次加1) |
Stack<Integer> stack = new Stack<>();
stack.push(10);
stack.push(20);
stack.push(30);
stack.push(40);
System.out.println(stack);
int ret = stack.pop();
System.out.println(ret);
int ret1 = stack.peek();
System.out.println(ret1);
boolean flg = stack.empty();
System.out.println(flg);
System.out.println(stack);
int index = stack.search(20);
System.out.println(index);
用顺序表实现一个栈
public class MyStack<T> {
private T[] elem;
private int top;
public MyStack() {
this.elem =(T[])new Object[10];
}
public void push(T element) {
if (this.top == this.elem.length) {
this.elem = Arrays.copyOf(this.elem, 2 * this.elem.length);
}
this.elem[top] = element;
top++;
}
public T pop(){
if(empty()){
throw new UnsupportedOperationException("栈为空");
}
T ret=this.elem[this.top-1];
this.top--;
return ret;
}
public T peek(){
if(empty()){
throw new UnsupportedOperationException("栈为空");
}
T ret=this.elem[this.top-1];
return ret;
}
public boolean empty(){
return this.top==0;
}
@Override
public String toString() {
return "MyStack{" +
"elem=" + Arrays.toString(elem) +
", top=" + top +
'}';
}
}
话说,栈能否通过单向链表实现呢? 当然可以啦!!! 只是 如果入栈用尾插法,入栈和出栈时间复杂度O(n);即使用last指向栈顶元素,入栈时间复杂度可变为O(1),但是出栈需要使用栈顶元素的前一个元素,时间复杂度仍为O(n);双向链表可以使入栈和出栈的时间复杂度均为O(1) 如果入栈用头插法,有head指向头元素,入栈和出栈的时间复杂度均为O(1),
队列(Queue)
概念
底层是链表 先进先出,即进到队头而且从队头出
使用队列
Queue<Integer> queue = new LinkedList<>();
队列的常用方法 | |
---|
boolean offer(E e) | 将一个元素入队 | E poll() | 获取队头元素,但不删除 | E peek() | 删除队头元素(出队),返回此元素 |
抛出异常 | 返回特殊值 |
---|
入栈boolean add(E e) | boolean offer(E e) | 出栈E remove() | E pop() | 获取栈顶元素 E element() | E peek() |
通过链表实现一个队列
用first指向队头;用last指向队尾 进队尾插;出队头删 时间复杂度都为O(1) 实现方法时注意判断对列是否为空
class Node{
private int val;
private Node next;
public Node(int val){
this.val=val;
}
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
public class MyQueue {
private Node first;
private Node last;
public void offer(int val){
Node node = new Node(val);
if(empty()){
this.first=node;
this.last=node;
}else{
this.last.setNext(node);
this.last=node;
}
}
public int poll(){
if(empty()) {
throw new UnsupportedOperationException("队列为空!!");
}
int ret = this.first.getVal();
this.first = this.first.getNext();
return ret;
}
public int peek(){
if(empty()){
throw new UnsupportedOperationException("队列为空!!!");
}
return this.first.getVal();
}
public boolean empty(){
return this.first==null;
}
}
|