大話數據結構----棧
棧的定義:
棧(stack)是限定盡在表尾進行插入和刪除操作的線性表。
從定義中可以看出,棧也是線性表,是一個特殊的線性表,之前說線性的表的時候,線性表可以在任意位置進行插入插入,而棧比線性表特殊的地方的就是不能隨意的插入和刪除了,棧的插入和刪除只能在規定的同一端進行,而被允許插入和刪除的一端稱為棧頂,另一端稱為棧底。
從棧的特性中我們能發現:1).棧是一種後進先出的線性表,因為棧只有一個出入口,每次出棧是最後進的那個先出去,後一個才能出去,就像我們出電梯一樣,裏面的人被阻住,只有外面的人出去,裏面的人才能出去。
2)棧的棧頂是在變化的,所以棧還得有一個棧頂指針,新元素入棧的後,棧頂指針要指向新棧頂,棧頂棧頂元素出棧時,棧頂指針也是需要變化指向新的棧頂
棧的 三種狀態-----棧空、棧滿、棧未滿
棧空時:棧頂指針(top)=-1
棧滿時:棧頂指針(top)=MAXSIZE-1;
棧未滿:就是占中存在元素,top指針還未達到MAXSIZE-1.
進棧和出棧操作
進棧
1).判斷棧是否已經滿了,如果滿了當然就入不了棧。
2)、棧頂指針+1,在新棧頂位置存入要進棧的元素。
出棧:
1).判斷棧是否為空,裏面沒有數據先出棧也沒有。
2).將棧頂元素出棧,棧頂指針-1.
Java 實現棧的基本操作
package JavaStack; import javax.swing.table.TableColumn; /* * 項目名稱:JavaStack * @author:wzc * @date 創建時間:2017年9月10日 下午2:22:08 * @Description:數據結構----棧 * @parameter **/ public class Stack<T> { public static final int MAXSIZE=10; private static final int T = 0; private T [] date=(T[])new Object[MAXSIZE]; int top; public Stack() { top=-1; } //判斷棧是否為空 public boolean isEmpty(){ if (top==-1) { return true; } returnfalse; } //判斷棧是否滿 public boolean isFull(){ if (top==MAXSIZE-1) { return true; } return false; } /*Method:push *Description:入棧操作 *param:T date 入棧的數據元素 */ public void push(T date){ //1.入棧之前判斷是否棧滿 if (isFull()) { System.out.println("棧已經滿了"); return; } top=top+1; this.date[top]=date; System.out.println(date+"已經入棧"); } /*Method:enclosing_method *Description:出棧操作 *param: */ public T pop(){ //出棧之前判斷呢棧是否為空 if (isEmpty()) { System.out.println("棧為空,無可出棧數據"); return null; } T date= this.date[top]; top=top-1; return date; } //輸出棧 中有多少元素 public int getLength(){ return top+1; } //輸出棧中所有元素 public void getDate(){ for(int i=0;i<=top;i++){ System.out.print(date[i]+" "); } System.out.println(); } }
測試一下:
@Test public void test() { Stack <Integer> stack=new Stack<>(); int length = stack.getLength(); System.out.println("棧長:"+length); stack.push(2); System.out.println("棧長"+stack.getLength()); stack.push(5); stack.push(9); System.out.println("棧長"+stack.getLength()); stack.getDate(); Integer pop = stack.pop(); System.out.println(pop+"出棧"); System.out.println("棧長"+stack.getLength()); stack.getDate(); stack.pop(); stack.pop(); System.out.println("棧長"+stack.getLength()); stack.getDate(); stack.pop(); }
測試結果::
共享棧
共享棧 是開辟一塊內存空間,兩個棧結構共用這一塊內存空間,每個棧占領這塊空間的一頭。
要求:兩個棧的數據類型要相同。
棧滿:判斷棧滿的條件是----top1+1=top2
棧空: 1.第一個棧空的條件:top=-1
2.第二個棧空的 條件:top2=MAXSIZE
在兩個棧對於空間需求相反的時候,利用共享棧可以有效的節約空間。
package JavaStack; /* * 項目名稱:JavaStack * @author:wzc * @date 創建時間:2017年9月10日 下午3:07:28 * @Description:共享棧 * @parameter * */ public class DoubleStack<T> { public static final int MAXSIZE=10; private T [] date=(T[])new Object[MAXSIZE]; int top1; int top2; public DoubleStack() { top1=-1; top2=MAXSIZE; } //判斷棧1是否為空 public boolean isEmpty1(){ if (top1==-1) { return true; } return false; } //判斷棧2是否為空 public boolean isEmpty2(){ if (top2==MAXSIZE) { return true; } return false; } //判斷棧是否滿 public boolean isFull(){ if (top1+1==top2) { return true; } return false; } /*Method:push *Description:入棧操作 *param:T date 入棧的數據元素,StackNum 哪個棧 */ public void push(T date,int StackNum){ //1.入棧之前判斷是否棧滿 if (isFull()) { System.out.println("棧已經滿了"); return; } if (StackNum==1) { top1=top1+1; this.date[top1]=date; System.out.println(date+"已經入棧"); }else if (StackNum==2) { top2=top2-1; this.date[top2]=date; System.out.println(date+"已經入棧"); } } /*Method:enclosing_method *Description:出棧操作 *param:StackNum ,哪個棧 */ public T pop(int StackNum){ //第一個棧出棧 if (StackNum==1) { //出棧之前判斷呢棧是否為空 if (isEmpty1()) { System.out.println("棧為空,無可出棧數據"); return null; } T date= this.date[top1]; top1=top1-1; return date; }else if (StackNum==2) {//第二個棧出棧 //出棧之前判斷呢棧是否為空 if (isEmpty2()) { System.out.println("棧為空,無可出棧數據"); return null; } T date= this.date[top2]; top2=top2+1; return date; } //棧錯誤 return null; } }
棧的鏈式存儲結構
利用單鏈表的思想,棧中元素在內存中的存儲位置是隨機的,只需要它的前驅能找到就行,然後對數據的操作仍然是從棧頂操作,依舊是後進先出。
對於進棧、出棧的實現思想還是一樣。
入棧:
1.入棧元素的指針域指向當前棧頂指針top指向的元素。
2.top指針+1,指向新的棧頂元素。
出棧
1.將出棧元素出棧;
2.將top指針-1,指向下一個元素;
package JavaStack; /* * 項目名稱:JavaStack * @author:wzc * @date 創建時間:2017年9月10日 下午3:26:54 * @Description:鏈式存儲棧結構 * @parameter * */ public class LinkStack <T>{ private class StackNode{ T date; StackNode next; } private StackNode top; private int count; public LinkStack() { count =0; top=null; } //判讀是否為空 public boolean isEmpty(){ if (count==0) { return true; } return false; } /*Method:push *Description:入棧操作 *param:date 入棧元素 */ public void push(T date){ StackNode newNode=new StackNode(); newNode.date=date; newNode.next=top; top=newNode; count++; System.out.println(date+"入棧"); } /*Method:pop *Description:出棧操作 *param: */ public T pop(){ if (isEmpty()) { return null; } StackNode date=top; top=top.next; date.next=null; System.out.println(date.date+"出棧"); return date.date; } public void getDate(){ StackNode tmp=top; while(tmp!=null){ System.out.print(tmp.date+" "); tmp=tmp.next; } System.out.println(); } }
大話數據結構----棧