关于栈的基础知识介绍

一、存储结构

栈是一种线性结构:先进后出,可用数组与链表两种方式来实现。

1.数组栈

用数组来实现栈(此处用int[]为例)。

  1. 用一个数组存放栈中元素,有一个栈顶指针
  2. 提供的方法:
// 将元素data入栈
public void push(int data)
// 返回并删除栈顶元素
public int pop()
// 返回栈顶元素
public int peek():
// 判断栈是否为空
public boolean isEmpty()
  1. 栈满不入栈(或扩充容量后入栈),栈空不出栈(栈空时抛出EmptyStackException)

1.1以int[]为例实现

import java.util.Arrays;
import java.util.EmptyStackException;

/**
 * 
* 

Description:栈:基于数组、int[] 实现

* @author 杨丽金 * @date 2018-3-31 * @version 1.0 */ public class MyStack_array { int[] stack; // 栈顶指针 int top=-1; public MyStack_array(){ // 初始化栈容量为5 stack=new int[5]; } /** * 入栈操作 * @param data */ public void push(int data){ ensureCapacity(); stack[++top]=data; } private void ensureCapacity() { if(top==stack.length-1){ // 栈满 int newLength=stack.length*2; stack=Arrays.copyOf(stack, newLength); } } /** * 取栈顶元素 * @return * @throws Exception */ public int peek(){ if(!isEmpty()){ return stack[top]; }else{ throw new EmptyStackException(); } } public boolean isEmpty() { if(top==-1){ return true; } return false; } /** * 返回并删除栈顶元素 * @throws Exception */ public int pop(){ int i=peek(); top--; return i; } /** * 打印栈中元素 */ public void printStack(){ // for(int i=0;i<=top;i++){ // System.out.print(stack[i]+" "); // } System.out.println(Arrays.toString(stack)); } public static void main(String[] args) { MyStack_array s=new MyStack_array(); s.push(1); s.push(2); s.push(3); s.push(4); System.out.println("栈未扩充空间时:"); s.printStack(); try { System.out.println("栈顶元素为:"+s.peek()); } catch (Exception e) { System.out.println("栈空,无栈顶元素"); } s.push(1); s.push(2); s.push(3); s.push(4); s.push(5); s.push(6); s.push(7); s.push(8); s.push(9); s.push(10); System.out.println("栈扩充空间时:"); s.printStack(); try { System.out.println("栈顶元素为:"+s.peek()); } catch (Exception e) { System.out.println("栈空,无栈顶元素"); } } }
关于栈的基础知识介绍_第1张图片
运行结果.png

1.2在上述基础上改造成泛型栈

/**
 * 
* 

Description:栈:基于数组、泛型 实现

* @author 杨丽金 * @date 2018-3-31 * @version 1.0 */ public class MyStack_array_generic { // 默认栈容量大小 private static final int DEFAULT_SIZE = 3; // 存储栈中元素 private E[] stack; // 栈顶指针 private int top=-1; public MyStack_array_generic(Class type){ this(type,DEFAULT_SIZE); } public MyStack_array_generic(Class type,int size){ // 构造函数中完成相关初始化操作 // 不能直接使用stack=new E[DEFAULT_SIZE]; stack=(E[]) Array.newInstance(type, size); } /** * 入栈 * @param data */ public void push(E data){ ensureCapacity(); stack[++top]=data; } private void ensureCapacity() { if(top==stack.length-1){ int newLength=stack.length*2; stack=Arrays.copyOf(stack, newLength); } } /** * 返回并删除栈顶元素 * @return * @throws Exception */ public E pop(){ E obj=peek(); top--; return obj; } private boolean isEmpty() { if(top==stack.length){ return true; } return false; } /** * 取栈顶元素 * @return * @throws Exception */ public E peek(){ if(isEmpty()){ throw new EmptyStackException(); }else{ return stack[top]; } } public void printStack(){ System.out.println(Arrays.toString(stack)); } public static void main(String[] args) { MyStack_array_generic s=new MyStack_array_generic(Person.class); s.push(new Person(10,"小红")); s.push(new Person(20,"小名")); s.push(new Person(30,"小李")); System.out.println("栈未扩充空间时:"); s.printStack(); try { System.out.println("栈顶元素为:"+s.peek()); } catch (Exception e) { System.out.println("栈空,无栈顶元素"); } s.push(new Person(10,"小红")); s.push(new Person(20,"小名")); s.push(new Person(30,"小李")); s.push(new Person(10,"haha")); s.push(new Person(20,"wwaa")); s.push(new Person(30,"caca")); s.push(new Person(30,"dfs")); System.out.println("栈扩充空间时:"); s.printStack(); try { System.out.println("栈顶元素为:"+s.peek()); } catch (Exception e) { System.out.println("栈空,无栈顶元素"); } } } class Person{ int age; String name; public Person(int age,String name){ this.age=age; this.name=name; } @Override public String toString() { return "Person [age=" + age + ", name=" + name + "]"; } }

2.链表栈

用链表存储栈,链表栈的实现使用的是链表的头插法

import java.util.EmptyStackException;

/**
 * 
 * 

* Description:用链表实现队列 *

* * @author 杨丽金 * @date 2018-3-31 * @version 1.0 */ public class MyStack_linkedList { // 栈顶指针 private Node top = null; // 将元素data入栈 public void push(E data) { Node newNode = new Node(data); if (isEmpty()) { top = newNode; } else { // 利用链表的头插法 newNode.next = top; top = newNode; } } // 返回并删除栈顶元素 public E pop() { if (top == null) { throw new EmptyStackException(); } else { Node ret = top; top = top.next; return ret.data; } } // 返回栈顶元素 public E peek() { if (top == null) { throw new EmptyStackException(); } else { return top.data; } } // 判断栈是否为空 public boolean isEmpty() { return top == null; } /** * 打印栈中元素 */ public void printStack() { Node cur = top; // 循环最重要的是:循环条件+迭代条件!! while (cur != null) {// 循环条件 System.out.print(cur.data + " "); cur = cur.next;// 迭代条件 } System.out.println(); } class Node { E data; Node next; public Node(E data) { this.data = data; next = null; } } public static void main(String[] args) { MyStack_linkedList s = new MyStack_linkedList(); try { System.out.println("栈顶元素为:" + s.peek()); } catch (Exception e) { System.out.println("栈空,无栈顶元素"); } s.push(new Person(10, "小红")); s.push(new Person(20, "小名")); s.push(new Person(30, "小李")); s.push(new Person(10, "haha")); s.push(new Person(20, "wwaa")); s.push(new Person(30, "caca")); s.push(new Person(30, "dfs")); s.printStack(); try { System.out.println("栈顶元素为:" + s.peek()); } catch (Exception e) { System.out.println("栈空,无栈顶元素"); } } }

二、 栈的应用

  1. 括号匹配
  2. 后缀表达式
  3. 栈在递归中的应用

你可能感兴趣的:(关于栈的基础知识介绍)