栈
栈的定义
- 栈是一种线性表的特殊表现形式,栈是按照后进后出的原则处理数据;类型结构分为顺序存储结构和链式存储结构;
- 顺序存储结构的特点——存储线性表的数据元素的方式是一段地址连续的存储单元;
- 链式存储结构的特点——存储线性表的数据元素的方式是一段地址不连续、任意的存储单元;
- 存储结构的对比:

栈的基本操作
栈的基本操作只有两个:
- 入栈(Push):即将数据保存到栈顶。进行该操作前,先修改栈顶指针,使其向上移一个元素位置,然后将数据保存到栈顶指针所指的位置 ;
- 出栈(Pop):即将栈顶的数据弹出,然后修改栈顶指针,使其指向栈中的下一个元素
栈的主要操作:
- 判断栈的状态 boolean empty();
- 返回栈中元素的数量 int size();
- 入栈操作 void push(E item);
- 出栈操作 E pop();
- 获取栈顶元素 E peek();
栈的实现
栈的实现方式有两种,一种是基于数组实现,一种是基于链表实现;
public interface Stack<E> {
//判断栈是否为空
public boolean empty();
//返回栈中元素数量
public int size();
//压栈
public void push(E item);
//弹栈
public E pop();
//查看栈顶元素(不弹栈)
public E peek();
}1:基于数组实现
import java.util.Arrays;
import java.util.EmptyStackException;
public class ArrayStack<E> implements Stack<E> {
private final static int DEFAULT_CAPACITY = 10;
private E[] data;
private int size;
private int top; //栈顶索引
public ArrayStack(int capacity) {
this.data = (E[]) new Object[capacity];
this.size = 0;
this.top = -1;
}
public ArrayStack(){
this(DEFAULT_CAPACITY);
}
@Override
public boolean empty() {
return size == 0;
}
@Override
public int size() {
return size;
}
@Override
public void push(E item) {
if(data.length == size) {
grow(data.length*2);
}
data[++top] = item;
size++;
}
private void grow(int capacity) {
if(capacity <= DEFAULT_CAPACITY){
return;
}
data = Arrays.copyOf(data, capacity);
}
@Override
public E pop() {
if(size == 0) {
throw new EmptyStackException();
}
if(size < data.length/2) {
grow(data.length/2);
}
size--;
return data[top--];
}
@Override
public E peek() {
if(size == 0) {
throw new EmptyStackException();
}
return data[top];
}
public static void main(String [] args){
Stack<Integer> stack = new ArrayStack();
for(int i=0; i<100; i++){
stack.push(i+1);
}
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
int size = stack.size();
for(int i=0; i<size; i++){
System.out.println("The element is: " + stack.pop());
}
}
}
2:基于链表实现
import java.util.Arrays;
import java.util.EmptyStackException;
public class LinkedStack<E> implements Stack<E> {
private static class Node<E>{
public E data;
public Node<E> next;
public Node(E val, Node<E> next) {
this.data = val;
this.next = next;
}
}
private Node<E> top;
private int size;
public LinkedStack(){
this.top = null;
this.size = 0;
}
@Override
public boolean empty() {
return size == 0;
}
@Override
public int size() {
return size;
}
@Override
public void push(E item) {
top = new Node(item, top);
size++;
}
@Override
public E pop() {
if(size == 0) {
throw new EmptyStackException();
}
E result = top.data;
top = top.next;
size--;
return result;
}
@Override
public E peek() {
if(size == 0) {
throw new EmptyStackException();
}
return top.data;
}
public static void main(String [] args){
Stack<Integer> stack = new LinkedStack();
for(int i=0; i<100; i++){
stack.push(i+1);
}
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
int size = stack.size();
for(int i=0; i<size; i++){
System.out.println("The element is: " + stack.pop());
}
}
}栈的应用
利用栈求算术表达式的值,中缀表达式转后缀表达式求解算法表达式?求后缀表达式的值?
队列
队列的定义
队列是一种特殊的线性表,特点是先进先出;其结构也分为链式存储结构和顺序存储结构;

只允许在表的前端进行删除操作,而在表的后端进行插入操作;
进行插入操作的端称为队尾;
进行删除操作的端称为队头;
存储结构对比
即,顺序存储结构(循环队列)和链式存储结构(链队列)对比

队列的实现
队列的实现方式有两种,一种是基于数组实现,一种是基于链表实现;
public interface Queue<E> {
//返回队列元素数量
public int size();
//队列是否为空
public boolean empty();
//入队
public void enqueue(E e);
//出队
public E dequeue();
//查看队首元素
public E peek();
}1:基于数组实现
import java.util.Arrays;
public class ArrayQueue<E> implements Queue<E> {
private static final int DEFAULT_CAPACITY = 10;
private E[] data;
private int size;
private int head;
private int tail;
public ArrayQueue(int capacity) {
this.data = (E[]) new Object[capacity];
this.size = 0;
this.head = -1;
this.tail = -1;
}
public ArrayQueue() {
this(DEFAULT_CAPACITY);
}
@Override
public int size() {
return size;
}
@Override
public boolean empty() {
return size == 0;
}
@Override
public void enqueue(E e) {
if(data.length == size) {
grow(data.length*2);
}
tail = (tail + 1) % data.length;
data[tail] = e;
if(size == 0){
head = tail;
}
size++;
}
private void grow(int capacity) {
if(capacity <= DEFAULT_CAPACITY) {
return;
}
E[] oldData = data;
data = (E[]) new Object[capacity];
for(int i=0; i<size; i++) {
data[i] = oldData[(head+i)%oldData.length];
}
head = 0;
tail = size - 1;
}
@Override
public E dequeue() {
if(size == 0) {
throw new RuntimeException("队列为空...");
}
E result = data[head];
head = (head + 1) % data.length;
size--;
if(size < data.length/2) {
grow(data.length/2);
}
return result;
}
@Override
public E peek() {
if(size == 0) {
throw new RuntimeException("队列为空...");
}
return data[head];
}
public static void main(String[] args) {
Queue<Integer> queue = new ArrayQueue<>();
for(int i=0; i<100; i++) {
queue.enqueue(i+1);
}
int size = queue.size();
for(int i=0; i<size; i++){
System.out.println("The element is: " + queue.dequeue());
}
}
}
2:基于链表实现
public class LinkedQueue<E> implements Queue<E> {
private static class Node<E> {
private E data;
private Node<E> next;
public Node(E val, Node<E> next) {
this.data = val;
this.next = next;
}
}
private Node<E> head;
private Node<E> tail;
private int size;
public LinkedQueue() {
this.head = null;
this.tail = null;
this.size = 0;
}
@Override
public int size() {
return size;
}
@Override
public boolean empty() {
return size == 0;
}
@Override
public void enqueue(E e) {
Node<E> prev = tail;
tail = new Node(e, null);
if(size == 0) {
head = tail;
}else{
prev.next = tail;
}
size++;
}
@Override
public E dequeue() {
if(size == 0) {
throw new RuntimeException("队列为空...");
}
E result = head.data;
head = head.next;
size--;
if(size == 0) {
tail = null;
}
return result;
}
@Override
public E peek() {
if(size == 0) {
throw new RuntimeException("队列为空...");
}
return head.data;
}
public static void main(String[] args) {
Queue<Integer> queue = new LinkedQueue<>();
for(int i=0; i<100; i++) {
queue.enqueue(i+1);
}
int size = queue.size();
for(int i=0; i<size; i++){
System.out.println("The element is: " + queue.dequeue());
}
}
}