1. 程式人生 > 實用技巧 >棧(Stack)

棧(Stack)

棧的介紹

  1. 棧的英文為:Stack
  2. 棧是一個先入後出(FILO-First In Last Out)的有序列表。
  3. 棧(stack)是限制線性表中元素的插入和刪除只能在線性表的同一端進行的一 種特殊線性表。允許插入和刪除的 一端,為變化的一端,稱為棧頂(Top),另一端為固定的一端,稱為棧底(Bottom)。
  4. 根據棧的定義可知,最先放入棧中元素在棧底,最後放入的元素在棧頂,而刪除元素剛好相反,最後放入的元素最先刪除,最先放入的元素最後刪除
  5. 圖解方式說明出棧(pop)和入棧(push)的概念:

棧的應用場景

  1. 子程式的呼叫:在跳往子程式前,會先將下個指令的地址存到堆疊中,直到子程式執行完後再將地址取出,以回到原來的程式中。
  2. 處理遞迴呼叫:和子程式的呼叫類似,只是除了儲存下一個指令的地址外,也將引數、區域變數等資料存入堆疊中。
  3. 表示式的轉換[中綴表示式轉字尾表示式]與求值。
  4. 二叉樹的遍歷。
  5. 圖形的深度優先(depth 一 first)搜尋法。

陣列實現棧

思路分析

  1. 使用陣列來模擬棧
  2. 定義一個top來表示棧頂,初始指向為-1
  3. 入棧操作:當資料加入到棧時,

top++

stack[top]=data;

  1. 出棧操作:

int value=stack[top];

top--;

return value;

程式碼實現:

1. //用陣列實現棧
2. publicclassarraystack{
3. private
int[]array;//陣列,陣列模擬棧,資料就放在該陣列 4. privateinttop=-1;//top表示棧頂,初始化為-1 5. privateintmaxSize;//棧的大小 6. 7. //構造器 8. publicarraystack(intmaxSize){ 9. this.maxSize=maxSize; 10. array=newint[this.maxSize]; 11. } 12. 13. //判斷棧是否為空 14. publicbooleanisEmpty(){ 15. returntop==-1; 16. } 17. 18. //判斷棧是否滿 19. publicbooleanisFull(){
20. returntop==this.maxSize-1; 21. } 22. 23. //入棧 24. publicvoidpush(inta){ 25. if(isFull()){//先判斷棧是否滿 26. System.out.println("push():棧已滿,無法新增。。。。"); 27. return; 28. } 29. top++; 30. array[top]=a; 31. } 32. 33. //出棧 34. publicintpop(){ 35. if(isEmpty()){//先判斷棧是否空 36. thrownewRuntimeException("pop():棧已滿,無法出棧。。。"); 37. } 38. inti=array[top]; 39. top--; 40. returni; 41. } 42. 43. //遍歷 44. publicvoidshow(){ 45. for(inti=top;i>-1;i--){//遍歷時,需要從棧頂開始顯示資料 46. System.out.println(array[i]); 47. } 48. } 49. 50. //獲取棧頂元素 51. publicintpeek(){ 52. returnarray[top]; 53. } 54. }

連結串列實現棧

程式碼實現:

  • 定義連結串列:
1. //定義連結串列
2. publicclasslinkedList<E>{
3. 
4. privateclassNode{//內部類,定義連結串列中的節點內容
5. privateNodenext;//表示下一個節點
6. Ee;//此節點的值
7. 
8. //構造器
9. publicNode(Ee,Nodenext){
10. this.next=next;
11. this.e=e;
12. }
13. 
14. //構造器
15. publicNode(){
16. this(null,null);
17. }
18. 
19. //構造器
20. publicNode(Ee){
21. this(e,null);
22. }
23. 
24. //重寫toString()
25. @Override
26. publicStringtoString(){
27. return"Node{"+
28. "e="+e+
29. '}';
30. }
31. }
32. 
33. privateNodefirst=newNode();//表示連結串列的頭結點
34. privateintsize;//表示連結串列的長度(大小)
35. 
36. //獲取連結串列中的元素個數
37. publicintgetSize(){
38. returnsize;
39. }
40. 
41. //返回連結串列是否為空
42. publicbooleanisEmpty(){
43. returnsize==0;
44. }
45. 
46. //在連結串列的index(0~size-1)位置新增新的元素e
47. publicvoidadd(intindex,Ee){
48. if(index<0||index>size){//判斷index是否合法
49. thrownewIllegalArgumentException("add():輸入index值有誤,新增失敗。。。");
50. }
51. Nodetemp=first;//頭結點不能移動,所以設定輔助節點temp
52. for(inti=0;i<index;i++){//將temp節點指向index位置的前一個位置節點
53. temp=temp.next;
54. }
55. Nodenode=newNode(e,temp.next);//將新元素e建立成node物件,next為temp的下一個節點
56. temp.next=node;//將temp所指節點的next指向node
57. size++;
58. }
59. 
60. //在連結串列頭新增新的元素e
61. publicvoidaddAtFirst(Ee){
62. add(0,e);
63. }
64. 
65. //在連結串列末尾新增新的元素e
66. publicvoidaddAtLast(Ee){
67. //add(getSize(),e);
68. add(size,e);
69. }
70. 
71. //獲得連結串列的第index(0~size-1)個位置的元素
72. publicEget(intindex){
73. if(index<0||index>=size){
74. thrownewIllegalArgumentException("get():輸入的index非法,獲取失敗。。。");
75. }
76. Nodetemp=first.next;
77. for(inti=0;i<index;i++){
78. temp=temp.next;
79. }
80. returntemp.e;
81. }
82. 
83. //獲得連結串列的第一個元素
84. publicEgetFirst(){
85. returnget(0);
86. }
87. 
88. //獲得連結串列的最後一個元素
89. publicEgetLast(){
90. returnget(size-1);
91. }
92. 
93. //修改連結串列的第index(0~size-1)個位置的元素為e
94. publicvoidset(intindex,Ee){
95. if(index<0||index>=size){
96. thrownewIllegalArgumentException("set():獲取元素失敗,輸入的index值非法!");
97. }
98. Nodetemp=first;
99. for(inti=0;i<index;i++){
100. temp=temp.next;
101. }
102. temp.e=e;
103. }
104. 
105. //查詢連結串列中是否有元素e
106. publicbooleancontains(Ee){
107. Nodetemp=first.next;
108. booleanflag=false;
109. while(temp!=null){
110. if(temp.e.equals(e)){
111. returntrue;
112. }
113. temp=temp.next;
114. }
115. returnfalse;
116. }
117. 
118. //從連結串列中刪除index(0~size-1)位置的元素,返回刪除的元素
119. publicEremove(intindex){
120. if(index<0||index>=size){
121. thrownewIllegalArgumentException("remove():獲取元素失敗,輸入的index值非法!");
122. }
123. Nodetemp=first;
124. for(inti=0;i<index;i++){
125. temp=temp.next;
126. }
127. NodedelNode=temp.next;
128. temp.next=delNode.next;
129. size--;
130. returndelNode.e;
131. }
132. 
133. 
134. //從連結串列中刪除第一個元素(0),返回刪除的元素
135. publicEremoveFirst(){
136. returnremove(0);
137. }
138. 
139. //從連結串列中刪除最後一個元素(size-1),返回刪除的元素
140. publicEremoveLast(){
141. returnremove(size-1);
142. }
143. 
144. //從連結串列中刪除指定元素e
145. publicvoidremoveElement(Ee){
146. Nodetemp=first;
147. while(temp.next!=null){
148. if(temp.next.e.equals(e)){
149. temp.next=temp.next.next;
150. size--;
151. return;
152. }
153. temp=temp.next;
154. }
155. System.out.println("removeElemen():沒有找到該元素,刪除失敗。。。");
156. }
157. 
158. //重寫toString()
159. @Override
160. publicStringtoString(){
161. StringBuilderstringBuilder=newStringBuilder();
162. Nodetemp=first.next;
163. while(temp!=null){
164. if(temp.next==null){
165. stringBuilder.append(temp.e);
166. }else{
167. stringBuilder.append(temp.e+"->");
168. }
169. temp=temp.next;
170. }
171. returnstringBuilder.toString();
172. }
173. }

來自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php> 
  • 用連結串列定義棧:
1. interfacestack<E>{
2. /**
3. *獲取棧的大小
4. */
5. intgetSize();
6. 
7. /**
8. *棧頂元素出棧
9. */
10. Epop();
11. 
12. /**
13. *元素入棧
14. */
15. voidpush(Ee);
16. 
17. /**
18. *遍歷棧元素
19. */
20. voidprintAll();
21. 
22. /**
23. *輸出棧頂元素
24. */
25. Epeek();
26. 
27. /**
28. *判斷棧是否為空
29. */
30. booleanisEmpty();
31. }

來自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php> 

1. //用連結串列來實現棧
2. classlinkedListStack<E>implementsstack<E>{
3. privatelinkedList<E>list;
4. 
5. publiclinkedListStack(){
6. list=newlinkedList<>();
7. }
8. 
9. @Override
10. publicintgetSize(){
11. returnlist.getSize();
12. }
13. 
14. @Override
15. publicEpop(){
16. returnlist.removeLast();
17. }
18. 
19. @Override
20. publicvoidpush(Ee){
21. list.addAtLast(e);
22. }
23. 
24. @Override
25. publicvoidprintAll(){
26. System.out.println(list.toString());
27. }
28. 
29. @Override
30. publicEpeek(){
31. EatLast=null;
32. try{
33. atLast=list.getLast();
34. }catch(Exceptione){
35. System.out.print("棧為空:");
36. }
37. returnatLast;
38. }
39. 
40. @Override
41. publicbooleanisEmpty(){
42. returnlist.isEmpty();
43. }
44. 
45. }

來自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php>