數據結構之基本數據結構---棧:先入后出
百度百科:
棧(stack)又名堆棧,它是一種運算受限的線性表。限定僅在表尾進行插入和刪除操作的線性表。這一端被稱為棧頂,相對地,把另一端稱為棧底。
向一個棧插入新元素又稱作進棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧,它是
把棧頂元素刪除掉,使其相鄰的元素成為新的棧頂元素。
自定義棧:
示例代碼:
package stack; /** * @Author YangHe * @Date 2020/4/14 11:27 * 手動實現:棧的基本操作 * 后進先出 LIFO */ public class StackTest { private final int stackSize; //棧可用最大容量 private int base; //棧底指針 private int top; //棧頂指針 private int[] array; //存儲使用數組實現 //初始化棧 public StackTest(int stackSize) { this.stackSize = stackSize; this.base=-1; this.top=-1; this.array=new int[stackSize]; } //判斷棧是否為空 public boolean isEmpty(){ return base==top; } //判斷棧是否滿 public boolean isFull(){ return (top-base)>=stackSize; } //獲取棧的長度 public int getStackLength(){ return top-base; } //出棧但不刪除(指針不移動) public int peek(){ if(!isEmpty()){ return array[top]; }else{ System.out.println("棧為空,返回-1"); return -1; } } //出棧並且刪除(指針移動) public int pop(){ if(!isEmpty()){ return array[top--]; }else{ System.out.println("棧為空,返回-1"); return -1; } } //入棧 public void push(int n){ if(!isFull()){ array[++top]=n; }else{ System.out.println(top); System.out.println("棧已滿"); } } //銷毀棧 public void stackDestroy(){ array=null; top=-1; } public static void main(String[] args) { StackTest stackTest=new StackTest(10); for(int i=0;i<3;i++){ stackTest.push(i); System.out.println("入棧元素"+i+" 棧長度:"+stackTest.getStackLength()); } for(int i=0;i<3;i++){ System.out.println("不刪除棧頂元素出棧:"+stackTest.peek()+" 棧長度:"+stackTest.getStackLength()); } for(int i=0;i<3;i++){ System.out.println("刪除棧頂元素出棧:"+stackTest.pop()+" 棧長度:"+stackTest.getStackLength()); } stackTest.stackDestroy(); System.out.println("銷毀棧之后長度為:"+stackTest.getStackLength()); } }
示例結果:
Stack類:
List接口下Vector類的子類Stack 也可以模擬 “棧”這種數據結構
示例代碼:
package stack; import java.util.Stack; /** * @Author YangHe * @Date 2020/4/14 16:24 * Vector下的Stack子類: 模擬 “棧”這種數據結構 * 后進先出 LIFO */ public class VectorStack { public static void main(String[] args) { Stack v=new Stack(); //入棧 v.push("Java基礎"); v.push("python基礎"); v.push("MySQL基礎"); v.push("Linux基礎"); System.out.println("當前棧長度為:"+v.size()); //出棧 並不刪除 System.out.println("出棧但不刪除棧頂元素:"+v.peek()+" 出棧后當前棧長度為:"+v.size()); System.out.println("出棧但不刪除棧頂元素:"+v.peek()+" 出棧后當前棧長度為:"+v.size()); //出棧 刪除元素 System.out.println("出棧刪除棧頂元素:"+v.pop()+" 出棧后當前棧長度為:"+v.size()); System.out.println("出棧刪除棧頂元素:"+v.pop()+" 出棧后當前棧長度為:"+v.size()); } }
示例結果:
以下為我寫的兩個棧的應用(進制轉換,表達式計算):
示例代碼:
package stack; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Author YangHe * @Date 2020/4/16 14:34 * 使用棧的實例 */ public class Example { /** * 進制轉換 * @param parameter 要轉換的十進制數 * @param scale 進制數 * @return */ public static long hexConversion(int parameter,int scale){ StackTest stackTest=new StackTest(Integer.class,50); while(true){ //進行計算入棧 if(parameter>=scale){ int a=parameter/scale; int b=parameter%scale; stackTest.push(b); parameter=a; }else{ stackTest.push(parameter); break; } } long result=stackTestToIntTool(stackTest); //將獲取的棧數據轉化成long類型進行展示 return result; } /** * 表達式運算 暫未實現運算符優先級 * @param expression * @return */ public static StackTest<String> compute(String expression){ StackTest stackTest=new StackTest(String.class,50); Pattern p; Matcher m; p = Pattern.compile("\\+|\\-|\\*|\\/|\\(|\\)|\\[|\\]|[1-9]\\d*\\.?\\d*"); m = p.matcher(expression); while(m.find()){ String str=m.group(); if(str.equals(")")){ int result=0; while(!stackTest.peek().equals("(")){ Integer a=Integer.valueOf(stackTest.pop().toString()); String x=stackTest.pop().toString(); Integer b=Integer.valueOf(stackTest.pop().toString()); result=calculate(a,x,b); } stackTest.pop(); stackTest.push(String.valueOf(result)); }else if(str.equals("]")){ int result=0; while(!stackTest.peek().equals("[")){ Integer a=Integer.valueOf(stackTest.pop().toString()); String x=stackTest.pop().toString(); Integer b=Integer.valueOf(stackTest.pop().toString()); result=calculate(a,x,b); } stackTest.pop(); stackTest.push(String.valueOf(result)); }else{ stackTest.push(str); } } while(stackTest.getStackLength()>1){ Integer a=Integer.valueOf(stackTest.pop().toString()); String x=stackTest.pop().toString(); Integer b=Integer.valueOf(stackTest.pop().toString()); stackTest.push(String.valueOf(calculate(a,x,b))); } return stackTest; } /** * stackTest轉化為long類型數 * @param stackTest * @return */ public static long stackTestToIntTool(StackTest stackTest){ String str=""; while(!stackTest.isEmpty()){ str+=stackTest.pop(); } return Long.valueOf(str); } /** * 進行計算 * @param a * @param x * @param b * @return */ public static int calculate(int a,String x,int b){ if(x.equals("+")){ return a+b; }else if(x.equals("-")){ return b-a; }else if(x.equals("*")){ return a*b; }else if(x.equals("/")){ return b/a; } return 0; } /** * 打印棧 * @param stringStackTest */ public static void print(StackTest<String> stringStackTest){ while(stringStackTest.isEmpty()){ System.out.println(stringStackTest.pop()); } } public static void main(String[] args) { System.out.println("-----進制轉換-----"); System.out.println("123456 轉換2進制:"+hexConversion(123456,2)); System.out.println("123456 轉換4進制:"+hexConversion(123456,4)); System.out.println("123456 轉換8進制:"+hexConversion(123456,8)); System.out.println("-----表達式計算-----"); String str="9+[(11+6)*3]+6+9"; StackTest<String> stringStackTest=compute(str); System.out.print(str+" 表達式計算結果為:"); while(!stringStackTest.isEmpty()){ System.out.print(stringStackTest.pop()); } } }
示例結果: