堆栈
来源:互联网 发布:网络暴力相关事件 编辑:程序博客网 时间:2024/06/07 20:50
堆栈
栈在计算机中的应用极其广泛,非常的重要。比如,递归就是依靠栈来实现的,每个浏览器都会提供一个回退之前网页的功能,这也是栈的应用。
需要注意的是,栈是一种特殊的线性表,既然是线性表,就有顺序存储结构,和链式存储结构,后面都会给出代码实现。
展示一下栈的抽象数据类型
ADT 栈(stack)Data 一种特殊的线性表,只能在尾部进行添加和删除操作Operation InitStack() 初始化 DestoryStack() 销毁栈 ClearStack() 清空栈 StackEmpty() 检测栈是否为空 GetTop() 得到栈顶元素 Push(E e) 添加元素 Pop() 删除元素 StackLength() 返回栈的元素个数
栈的顺序表实现代码:
public class Stack1<E>{ private static final int defLen = 20; private Object[] data = null; private int length; private int size; public Stack1(){ this.data = new Object[defLen]; this.size = defLen; this.length = 0; } public Stack1(int size){ this.data = new Object[size]; this.size = size; this.length = 0; } protected int getLength(){ return this.length; } protected int getSize(){ return this.size; } protected boolean empty(){ if(this.length == 0) return true; return false; } protected E peek(){ return (E) this.data[this.length - 1]; } protected boolean push(E e){ if(this.length > this.size) return false; this.data[this.length] = e; this.length++; return true; } protected E pop(){ if(this.length == 0){ return null; } this.length--; return (E) this.data[this.length]; }}
栈的链式存储实现代码:
public class Stack2<E>{ private class Node{ public Node(E e) { this.e = e; } public Node(){ } protected E getE() { return e; } protected void setE(E e) { this.e = e; } protected Node getNext() { return next; } protected void setNext(Node next) { this.next = next; } private E e; private Node next; } private int length; private final static int defLen = 20; private Node head = new Node(); public Stack2() { super(); } protected boolean empty(){ return this.length == 0; } private Node get(int p){ Node node = head; for(int i = 0;i < p;i++){ node = node.getNext(); } return node; } protected E peek(){ return get(this.length).getE(); } protected E pop(){ this.length--; return get(this.length + 1).getE(); } protected void push(E e){ Node n = new Node(e); get(this.length).setNext(n); this.length++; } }
栈的另一个典型应用,是可以用来计算四则运算表达式,如:19+(3-1)*300+10/2
public class RPN { private RPN(){ } private static Stack<String> stack1 = new Stack<String>(); private static Stack<String> stack2 = new Stack<String>(); private static ArrayList<String> list2 = new ArrayList<String>(); public static int getResult(String str){ //1将字符串中的元素一个个提取出来,装进List容器中 ArrayList<String> list1 = getElem(str); //2将得到的中缀表达式转换为后缀表达式 //2.1 遍历 list1 ,把后缀表达式装到 list2 中去 for(String s : list1){ if(sss(s)){//是符号 pushDef(s); }else{ list2.add(s); } } pushDef("end"); //3 遍历 list2 ,利用后缀表达式来求得最终的值 for(String s : list2){ if(sss(s)){ s = String.valueOf(Calc(s)); } stack2.push(s); } return Integer.valueOf(stack2.peek()); } // /** * 后缀表达式求值时,如果是符号,则调用此方法 * 返回的是栈顶的两个元素运算的值 */ private static int Calc(String s) { int b = Integer.valueOf(stack2.pop()); int a = Integer.valueOf(stack2.pop()); int result = 0; switch(s){ case"+": result = a+b; break; case"-": result = a-b; break; case"*": result = a*b; break; case"/": result = a/b; break; } return result; } /** * 中缀表达式求后缀表达式时,选择是否应该把元素压进栈中 */ private static void pushDef(String s) { if(stack1.empty() || f1(s)){ stack1.push(s); } if(s.equals("end")){ while(stack1.peek().equals(null)){ list2.add(stack1.pop()); } } } /** * 中缀表达式求后缀表达式时,判断是否符合压入栈中的规则 */ private static boolean f1(String s) { if(Getpro(s) == 3){ while(!stack1.peek().equals("(")){ list2.add(stack1.pop()); } stack1.pop(); return false; } if(Getpro(s) >= Getpro(stack1.peek())){ return true; }else{ while(!stack1.isEmpty() && Getpro(stack1.peek()) >= Getpro(s)){ list2.add(stack1.pop()); } if(stack1.isEmpty()){ return true; } } return false; } /** * 返回符号对应的优先级别 */ private static int Getpro(String s) { switch(s){ case "+": return 1; case "-": return 1; case "*": return 2; case "/": return 2; case "(": return 1; case ")": return 3; } return -1; } /** * 解析原始的表达式,放到容器中 */ private static ArrayList<String> getElem(String str){ char[] charArray = str.toCharArray(); ArrayList<String> list = new ArrayList<String>(); String s =""; for(int i = 0;i < charArray.length;i++){ if(i != charArray.length - 1){ s = String.valueOf(charArray[i+1]); if(sss(s)){ list.add(String.valueOf(charArray[i])); }else{ s = String.valueOf(charArray[i]); if(sss(s)){ list.add(String.valueOf(charArray[i])); }else{ while((i < charArray.length-1) && (!sss(String.valueOf(charArray[i+1]))) ){ s+=String.valueOf(charArray[i+1]); i++; } list.add(s); } } }else{ list.add(String.valueOf(charArray[i])); } } return list; } /** * 判断是否是符号 */ private static boolean sss(String s){ if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/") || s.equals("(") || s.equals(")")){ return true; } return false; }}
阅读全文
0 0
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- 堆栈
- #UVA1626#Brackets sequence(括号序列---石子归并类Dp)
- x264源代码简单分析:宏块编码(Encode)部分
- 期望为线性时间的选择算法
- Java Client API for RabbitMQ
- 大数据表转移hdfs后查询处理
- 堆栈
- 响应式布局-----媒体查询
- 关于position:relative,absolute,fixed和static
- x264源代码简单分析:熵编码(Entropy Encoding)部分
- react+react-router+redux开发体育馆管理系统(2)--需求分析,完善目录
- ubuntu14.04搭建(迁移)hustoj记录
- CSS选择器
- 百练_2680:化验诊断
- 普通GPIO模拟SPI通信协议(软件SPI)