一、链式堆栈
链式存储结构的堆栈称作链式堆栈。
与单链表相同,链式堆栈也是由一个个结点组成的,每个结点由两个域组成,一个是存放数据元素的数据元素域element,另一个是存放指向下一个结点的对象引用(即指针)域next。
堆栈有两端,插入数据元素和删除数据元素的一端为栈顶,另一端为栈底。链式堆栈都设计成把靠近堆栈头head的一端定义为栈顶。
依次向链式堆栈入栈数据元素a0, a1, a2, ..., an-1后,链式堆栈的示意图如图所示。
二、实现
public class Node { Object element; Node next; //头结点的构造方法 public Node(Node nextval) { this.next=nextval; } //不带头结点的构造方法 public Node(Object obj,Node nextval) { this.element=obj; this.next=nextval; } public Object getElement() { return element; } public void setElement(Object element) { this.element = element; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } @Override public String toString() { return this.element.toString(); } }
public interface Stack { //入栈 public void push(Object obj) throws Exception; //出栈 public Object pop() throws Exception; //得到栈顶元素 public Object getTop() throws Exception; //判断栈是否为空 public boolean isEmpty(); }
public class LinkedStack implements Stack { //栈顶指针 Node head; //节点个数 int size; public LinkedStack() { head=null; size=0; } @Override public void push(Object obj) throws Exception { head=new Node(obj,head); size++; } @Override public Object pop() throws Exception { if(isEmpty()) { throw new Exception("栈为空!"); } Object obj=head.getElement(); head=head.getNext(); size--; return obj; } @Override public Object getTop() throws Exception { return head.getElement(); } @Override public boolean isEmpty() { return head==null; } }三、堆栈的应用:堆栈是各种软件系统中应用最广泛的数据结构之一。括号匹配和表达式计算是编译软件中的基本问题,其软件设计中都需要使用堆栈。
1、括号匹配问题
public class Main { public static String[] splitStringtoArray(String exp) { int len=exp.length(); String array[]=new String[len]; for (int i = 0; i < len; i++) { array[i]=exp.substring(i, i+1); } return array; } //括号匹配是否正确 public static void sigleCheck(String exp) throws Exception{ SquenceStack stack=new SquenceStack(); String arr[]=splitStringtoArray(exp); for (int i = 0; i < arr.length; i++) { if(arr[i].equals("(")||arr[i].equals("[")||arr[i].equals("{")) { stack.push(arr[i]); }else if(arr[i].equals(")")&&!stack.isEmpty()&&stack.getTop().equals("(")) { stack.pop(); }else if(arr[i].equals(")")&&!stack.isEmpty()&&!stack.getTop().equals("(")) { System.out.println("括号匹配次序不正确!"); return; }else if(arr[i].equals("]")&&!stack.isEmpty()&&stack.getTop().equals("[")) { stack.pop(); }else if(arr[i].equals("]")&&!stack.isEmpty()&&!stack.getTop().equals("[")) { System.out.println("括号匹配次序不正确!"); return; }else if(arr[i].equals("}")&&!stack.isEmpty()&&stack.getTop().equals("{")) { stack.pop(); }else if(arr[i].equals("}")&&!stack.isEmpty()&&!stack.getTop().equals("{")) { System.out.println("括号匹配次序不正确!"); return; }else if(arr[i].equals(")")||arr[i].equals("]")||arr[i].equals("}")&&!stack.isEmpty()){ System.out.println("右括号多于左括号!"); return; } } if(!stack.isEmpty()) { System.out.println("左括号多于右括号!"); }else { System.out.println("括号匹配正确!"); } } public static void main(String[] args) throws Exception{ /*SquenceStack stack=new SquenceStack(10); Scanner scanner=new Scanner(System.in); int temp; for(int i=0;i<10;i++) { System.out.println("请输入第"+(i+1)+"个元素!"); temp=scanner.nextInt(); stack.push(temp); } while(!stack.isEmpty()) { System.out.println(stack.pop()); } scanner.close();*/ //String exp="{a*b+(c/d)[334-78]}"; //String exp="[{a*b+(c/d)[334-78]}"; String exp="{a*b+(c/d)[334-78]}]"; sigleCheck(exp); } }
2、表达式计算问题
扫描二维码关注公众号,回复: 1601582 查看本文章import java.io.IOException; import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception{ /*LinkedStack stack=new LinkedStack(); Scanner scanner=new Scanner(System.in); int temp; for(int i=0;i<10;i++) { System.out.println("请输入第"+(i+1)+"个元素!"); temp=scanner.nextInt(); stack.push(temp); } while(!stack.isEmpty()) { System.out.println(stack.pop()); } scanner.close();*/ LinkedStack stack=new LinkedStack(); exeCalcute(stack); } //表达式计算 public static void exeCalcute(LinkedStack stack) throws Exception { //输入的字符 char ch; //x1,x2:操作数 b:想表达式字符的ASSIC码 int x1,x2,b=0; System.out.println("输入后缀表达式并以#符号结束:"); while((ch=(char)(b=System.in.read()))!='#') { if(Character.isDigit(ch)) { stack.push(new Integer(Character.toString(ch))); }else { x2=(Integer)stack.pop(); x1=(Integer)stack.pop(); switch (ch) { case '+': x1+=x2; break; case '-': x1-=x2; break; case '*': x1*=x2; break; case '/': if(x2==0) { throw new Exception("除数不能为零!"); }else { x1/=x2; } break; } stack.push(new Integer(x1)); } } System.out.println("后缀表达式的结果是:"+stack.getTop()); } }