- 码云:https://gitee.com/yin_zhipeng/data_structures_and_algorithms_in_java.git
1. 堆栈,先入后出的数据结构。
2. 同一时刻只允许访问一个数据项,也就是最后一个数据
一、堆栈
1. 数组实现(Stack Array Implementation)
- 入栈
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/04322741e2d647775edc5204785a904e.gif)
- 出栈
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/9e06b0b99336e599c868c636629dedad.gif)
- 定义一个数组表示栈
- 定义一个变量top指向可以入栈的位置初始为0(也可以初始-1,指向最后一个数据)
- 入栈:以top为下标插入数据,然后top后移
- 出栈:以top为下标取出数据,然后top前移
代码:com/yzpnb/data_structures/stack/array_implementation/Stack.java |
---|
- 运行效果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/eb0193a5eacb8d8f553675b540d52b3d.png)
import java.util.Arrays;
public class Stack<E> {
private int top = 0;
private Object[] array;
public Stack(){
this.array = new Object[10];
System.out.println("栈初始成功!!!初始大小10");
}
public Stack(int size){
this.array = new Object[size];
System.out.println("栈初始成功!!!初始大小"+size);
}
public boolean isFull(){
return top==array.length;
}
public boolean isEmpty(){
return top == 0;
}
private void arrayExtend(){
array = Arrays.copyOf(array, array.length * 2);
}
public void push(E o){
if(isFull()){
arrayExtend();
System.out.println("栈满扩容");
}
array[top] = o;
top++;
System.out.println((E)o+"入栈成功");
}
public E peek(){
if(isEmpty()){
return null;
}
return (E)array[top-1];
}
public E pop(){
if(top == 0){
throw new RuntimeException("栈已空!!!");
}
System.out.print("出栈");
return (E)array[--top];
}
public static void main(String[] args) {
Stack<Integer> integerStack = new Stack<>(2);
integerStack.push(1);
integerStack.push(2);
integerStack.push(3);
System.out.println(integerStack.pop());
System.out.println(integerStack.pop());
System.out.println(integerStack.pop());
System.out.println(integerStack.pop());
}
}
2. 链表实现(Linked List Implementation)
- 入栈
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/669f22c006d14ab769cee74f94003ba2.gif)
- 出栈
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/c045b94550378e3a2cf5204f05e89426.gif)
- 定义一个链表作为栈,链表每个结点拥有一个前驱
- 定义一个变量top指向栈尾(链表最后一个结点)
- 入栈:链表长度为空,top指向当前插入结点,当前插入结点前驱为null;否则让新插入结点前驱指向当前top指向的结点,然后top指向当前插入结点
- 出栈:top当前指向结点返回,top前移
代码:com/yzpnb/data_structures/stack/linked_list_implementation/Stack.java |
---|
- 运行效果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/62a8ea9004d32ed65b1474217b39cda6.png)
public class Stack<E> {
private static class Node<E> {
E item;
Stack.Node<E> prev;
Node(Node<E> prev, E element) {
this.item = element;
this.prev = prev;
}
}
private Node<E> top = null;
private final Integer MAXSIZE = 65536;
private Integer size = 6;
private Integer length = 0;
public Stack(){
System.out.println("栈初始成功,当前栈没有元素,大小为6");
}
public Stack(int size){
this.size = size;
System.out.println("栈初始成功,当前栈没有元素,大小为"+size);
}
public Stack(E e){
Node<E> eNode = new Node<>(null, e);
this.length++;
this.top = eNode;
System.out.println("栈初始成功!!!当前栈顶元素为:"+top.item+",栈大小为6");
}
public Stack(E e,int size){
this.size = size;
Node<E> eNode = new Node<>(null, e);
this.top = eNode;
this.length++;
System.out.println("栈初始成功!!!当前栈顶元素为:"+top.item+",栈大小为"+size);
}
public boolean isFull(){
return length == size;
}
public boolean isEmpty(){
return length == 0;
}
private void extendStack(){
if(size == MAXSIZE){
throw new RuntimeException("栈大小已达上限!!!");
}
if(size*2>=MAXSIZE){
size = MAXSIZE;
}else if(size*2<MAXSIZE) {
size *= 2;
}
}
public void push(E e){
if(isFull()){
extendStack();
System.out.println("栈满扩容");
}
if(top == null){
Node<E> eNode = new Node<>(null, e);
this.top = eNode;
this.length++;
}else{
Node<E> eNode = new Node<>(top, e);
this.top = eNode;
this.length++;
}
System.out.println((E)e+"入栈成功");
}
public E peek(){
if(isEmpty()){
return null;
}
return top.item;
}
public E pop(){
if(isEmpty()){
throw new RuntimeException("栈已空!!!");
}
System.out.print("出栈");
E item = top.item;
top = top.prev;
this.length--;
return item;
}
public static void main(String[] args) {
Stack<Integer> integerStack = new Stack<>(2);
integerStack.push(1);
integerStack.push(2);
integerStack.push(3);
System.out.println(integerStack.pop());
System.out.println(integerStack.pop());
System.out.println(integerStack.pop());
System.out.println(integerStack.pop());
}
}
二、实战
1. 字符串反转
- 利用栈先进后出特性,依次入栈字符串,然后依次出栈,即可完成反转
- 入栈
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/f3f9181b63c9f408128d02e4eb36b995.gif)
- 出栈
![请添加图片描述](https://i-blog.csdnimg.cn/blog_migrate/ba453a18b9b84f3174078788ef2130ca.gif)
- 运行效果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0e61ebd45b25f49555dd1b7dde71be63.png)
import com.yzpnb.data_structures.stack.array_implementation.Stack;
public class StringReverse {
public static void main(String[] args) {
String str = "apple";
Stack<Character> characterStack = new Stack<>();
for (char c : str.toCharArray()) {
characterStack.push(c);
}
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0;i<str.length();i++){
stringBuffer.append(characterStack.pop());
}
System.out.println("\n"+str+"---字符串反转后---"+stringBuffer);
}
}
2. 括号匹配
- 判断字符串中的括号是否配对“a{b(]c}d”,比如这个字符串“(”找不到配对,则程序结束返回不匹配
- 遇到左括号,就入栈
- 遇到右括号,出栈,比较,不配对程序结束
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/3ba2449ed95d19250ce602c1045514b5.png)
代码:com/yzpnb/data_structures/stack/example/bracket_match/BracketMatch.java |
---|
- 运行效果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/d22760dd09a6387d96153b1d91cdaf3c.png)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/83d64651926bfa54cfda5d4b5e9c2e9d.png)
import com.yzpnb.data_structures.stack.linked_list_implementation.Stack;
public class BracketMatch {
public static void main(String[] args) {
String str = "a{b(]c}d";
Stack<Character> stack = new Stack<>();
System.out.println("开始匹配字符串:"+str+"的括号是否匹配");
for (Character c:str.toCharArray()) {
switch (c){
case '{' :
case '[' :
case '(' :{
stack.push(c);
break;
}
case ')':
case ']':
case '}':{
System.out.println("匹配右括号:"+c);
if(stack.isEmpty()){
System.out.println("不匹配");
return;
}
Character peek = stack.peek();
if(!check(c,stack.pop())){
System.out.println(peek+"与括号"+c+"不匹配");
return;
}
}
}
}
System.out.println("字符串括号完全匹配");
}
public static boolean check(char a,char b){
System.out.println();
switch (a) {
case '}':{
return b=='{';
}
case ']':{
return b=='[';
}
case ')':{
return b=='(';
}
}
return false;
}
}