栈
- 栈是一个先入后出的有序列表。
- 栈中元素的添加与删除都发生在线性表的同一端,允许插入和删除的一端被称为栈顶,另一端被称为栈底。
- 最先入栈的元素在栈底,最后入栈的元素在栈顶。最先删除的元素为最后入栈的元素,最后删除的元素为最先入栈的元素。
数组实现栈结构
- 主要是想push()和pop()两个方法,栈顶位于数组尾部,使用top来定位到栈顶(数组尾)
- 代码
import java.util.Scanner;
public class ArrayStackDemo {
public static void main(String[] args) {
ArrayStack stack = new ArrayStack(5);
char command = ' ';
boolean loop = true;
Scanner scan = new Scanner(System.in);
while(loop) {
System.out.println("向栈中添加元素:a");
System.out.println("从栈中取出元素:g");
System.out.println("打印栈中元素:p");
System.out.println("退出程序:e");
System.out.println("请输入命令:");
command = scan.next().charAt(0);
switch (command) {
case 'a':
System.out.println("请输入添加的数据:");
int value = scan.nextInt();
stack.push(value);
break;
case 'g':
try {
int num = stack.pop();
System.out.println(num);
}catch(Exception e) {
System.out.println(e.getMessage());
}
break;
case 'p':
stack.printStack();
break;
case 'e':
scan.close();
loop = false;
break;
default:
break;
}
}
System.out.println("退出程序。");
}
}
class ArrayStack{
private int size;
private int[] stack;
private int top = -1;
public ArrayStack(int size) {
this.size = size;
stack = new int[this.size];
}
public boolean isFull() {
return top == (size-1);
}
public boolean isEmpty() {
return top == -1;
}
public void push(int value) {
if(isFull()) {
System.out.println("栈已满,添加失败。");
return;
}
top++;
stack[top] = value;
}
public int pop() {
if(isEmpty()) {
throw new RuntimeException("栈为空,出栈失败。");
}
int value = stack[top];
top--;
return value;
}
public void printStack() {
if(isEmpty()) {
System.out.println("栈空,没有数据。");
return;
}
for(int i=top; i>=0; i--) {
System.out.println(stack[i]);
}
}
}
单链表实现栈结构
- 实现的栈的主要功能有:push()、pop()、打印、获取栈中元素个数。
- 代码
import java.util.Scanner;
public class ListStackDemo {
public static void main(String[] args) {
ListStack stack = new ListStack();
char command = ' ';
boolean loop = true;
Scanner scan = new Scanner(System.in);
while(loop) {
System.out.println("向栈中添加元素:a");
System.out.println("从栈中取出元素:g");
System.out.println("打印栈中元素:p");
System.out.println("获取元素个数:s");
System.out.println("退出程序:e");
System.out.println("请输入命令:");
command = scan.next().charAt(0);
switch (command) {
case 'a':
System.out.println("请输入添加的数据:");
int value = scan.nextInt();
stack.push(value);
break;
case 'g':
try {
int num = stack.pop();
System.out.println(num);
}catch(Exception e) {
System.out.println(e.getMessage());
}
break;
case 'p':
stack.printStack();
break;
case 's':
System.out.println("栈中元素个数:" + stack.getSize());
break;
case 'e':
scan.close();
loop = false;
break;
default:
break;
}
}
System.out.println("退出程序。");
}
}
class Node{
private int num;
private Node next;
public Node(int num) {
this.num = num;
}
public void setNum(int n) {
this.num = n;
}
public int getNum() {
return this.num;
}
public void setNext(Node node) {
this.next = node;
}
public Node getNext() {
return this.next;
}
}
class SingleLinkedList{
private Node head = new Node(0);
public boolean isEmpty() {
return head.getNext() == null;
}
public void addToHead(Node node) {
node.setNext(head.getNext());
head.setNext(node);
}
public Node deleteFromHead() {
if(isEmpty()) {
return null;
}
Node temp = head.getNext();
head.setNext(head.getNext().getNext());
return temp;
}
public void printList() {
if(isEmpty()) {
System.out.println("没有数据可以打印");
return;
}
Node temp = head.getNext();
while(temp != null) {
System.out.println(temp.getNum());
temp = temp.getNext();
}
}
public int getLength() {
if(isEmpty()) {
return 0;
}
int len = 0;
Node temp = head.getNext();
while(temp != null) {
len++;
temp = temp.getNext();
}
return len;
}
}
class ListStack{
private SingleLinkedList sll = new SingleLinkedList();
public void push(int num) {
Node node = new Node(num);
sll.addToHead(node);
}
public int pop() {
Node node = sll.deleteFromHead();
if(node == null) {
throw new RuntimeException("栈为空,没有数据。");
}
return node.getNum();
}
public void printStack() {
if(sll.isEmpty()) {
System.out.println("栈已空。");
return;
}
sll.printList();
}
public int getSize() {
return sll.getLength();
}
}
总结
- 使用 数组 和 链表 都可以实现栈结构。
数组:便于查询
链表:便于删除
栈:只在一端有数据的修改 - 显然可以使用多种结构(单链表、环形链表)实现栈结构,每种的实现方式也不同。一开始我打算使用 双向环形链表 实现栈结构,栈顶在双向环形链表的尾部,双向环形可以方便定位到栈顶,但显然是我把问题想复杂了。