一、棧的鏈式存儲結構,簡稱為鏈棧。思路就是把棧頂放在單鏈表的頭部,通常對於鏈棧來說,是不需要頭結點的。
二、鏈棧基本不存在棧滿的情況,除非內存已經沒有可以使用的空間。對於空棧來說,鏈表原定義是頭指針指向空,那么鏈棧的空其實就是top=NULL。
三、棧的鏈式存儲結構的C語言代碼實現:
#include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 20 /* 存儲空間初始分配量 */ typedef int Status; typedef int SElemType; /* SElemType類型根據實際情況而定,這里假設為int */ /* 鏈棧結構 */ typedef struct StackNode { SElemType data; struct StackNode *next; }StackNode,*LinkStackPtr; typedef struct { LinkStackPtr top; int count; }LinkStack; Status visit(SElemType c) { printf("%d ",c); return OK; } /* 構造一個空棧S */ Status InitStack(LinkStack *S) { S->top = (LinkStackPtr)malloc(sizeof(StackNode)); if(!S->top) return ERROR; S->top=NULL; S->count=0; return OK; } /* 把S置為空棧 */ Status ClearStack(LinkStack *S) { LinkStackPtr p,q; p=S->top; while(p) { q=p; p=p->next; free(q); } S->count=0; return OK; } /* 若棧S為空棧,則返回TRUE,否則返回FALSE */ Status StackEmpty(LinkStack S) { if (S.count==0) return TRUE; else return FALSE; } /* 返回S的元素個數,即棧的長度 */ int StackLength(LinkStack S) { return S.count; } /* 若棧不空,則用e返回S的棧頂元素,並返回OK;否則返回ERROR */ Status GetTop(LinkStack S,SElemType *e) { if (S.top==NULL) return ERROR; else *e=S.top->data; return OK; } /* 插入元素e為新的棧頂元素 */ Status Push(LinkStack *S,SElemType e) { LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode)); s->data=e; s->next=S->top; /* 把當前的棧頂元素賦值給新結點的直接后繼,見圖中① */ S->top=s; /* 將新的結點s賦值給棧頂指針,見圖中② */ S->count++; return OK; } /* 若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR */ Status Pop(LinkStack *S,SElemType *e) { LinkStackPtr p; if(StackEmpty(*S)) return ERROR; *e=S->top->data; p=S->top; /* 將棧頂結點賦值給p,見圖中③ */ S->top=S->top->next; /* 使得棧頂指針下移一位,指向后一結點,見圖中④ */ free(p); /* 釋放結點p */ S->count--; return OK; } Status StackTraverse(LinkStack S) { LinkStackPtr p; p=S.top; while(p) { visit(p->data); p=p->next; } printf("\n"); return OK; } int main() { int j; LinkStack s; int e; if(InitStack(&s)==OK) for(j=1;j<=10;j++) Push(&s,j); printf("棧中元素依次為:"); StackTraverse(s); Pop(&s,&e); printf("彈出的棧頂元素 e=%d\n",e); printf("棧空否:%d(1:空 0:否)\n",StackEmpty(s)); GetTop(s,&e); printf("棧頂元素 e=%d 棧的長度為%d\n",e,StackLength(s)); ClearStack(&s); printf("清空棧后,棧空否:%d(1:空 0:否)\n",StackEmpty(s)); return 0; } 輸出為: 棧中元素依次為:10 9 8 7 6 5 4 3 2 1 彈出的棧頂元素 e=10 棧空否:0(1:空 0:否) 棧頂元素 e=9 棧的長度為9 清空棧后,棧空否:1(1:空 0:否)
四、棧的鏈式存儲空間的Java語言代碼實現:
- 接口類:
package bigjun.iplab.linkStack; public interface IListStack { // 判斷順序棧是否為空 public boolean isStackEmpty(); // 將一個已經存在的順序棧置成空表 public void stackClear(); // 求順序棧的長度 public int stackLength(); // 讀取順序棧的棧頂元素 public int getTopElem() throws Exception; // 在順序棧中插入元素e public void stackPush(int e); // 刪除順序棧中的棧頂元素 public void stackPop() throws Exception ; // 輸出順序棧中的所有元素 public void stackTraverse(); }
- 節點類:
package bigjun.iplab.linkStack; public class Node { public Integer data; // 存放結點的數據元素的數據域(int類型不能設置null,而Integer類型可以) public Node next; // 存放后繼元素的引用 // 可實現初始化一個空的結點 public Node() { this(null, null); } // 可實現構造一個數據域值為指定參數值,而指針域為空的結點 public Node(Integer data) { this(data, null); } // 可實現構造一個數據域和指針域值都為指定參數的結點 public Node(Integer data, Node next) { this.data = data; this.next = next; } }
- 實現類:
package bigjun.iplab.linkStack; public class LinkStack implements IListStack { public Node top; public LinkStack() { top = new Node(); } public boolean isStackEmpty() { return top == null; } public void stackClear() { top = null; } public int stackLength() { Node pNode = top; // 初始化,pNode指向棧頂元素 int length = 0; // length為計數器 while (pNode != null) pNode = pNode.next; ++length; return length; } @Override public int getTopElem() throws Exception { if (!isStackEmpty()) { return top.data; } else { throw new Exception("棧為空,無法獲取棧頂元素"); } } public void stackPush(int e) { Node p = new Node(e); p.next = top; top = p; } public void stackPop() throws Exception { if (isStackEmpty()) throw new Exception("棧為空,無法彈出棧頂元素"); else { top = top.next; } } public void stackTraverse() { // 從棧頂元素到棧底元素 Node p = top; System.out.print("此時,鏈棧中的元素為: "); while (p.data != null) {// 這塊有一個問題,就是由於Node類的構造函數的原因,第一個Node的data會為空,如果用p != null的話,就會輸出一個null System.out.print(p.data + " "); p = p.next; } System.out.println(); } public static void main(String[] args) throws Exception { LinkStack lStack = new LinkStack(); for (int j = 1; j <= 10; j++) { lStack.stackPush(j); } lStack.stackTraverse(); System.out.println("棧頂元素為: " + lStack.getTopElem()); System.out.println("棧是否為空: " + lStack.isStackEmpty()); lStack.stackPop(); lStack.stackTraverse(); System.out.println("棧頂元素為: " + lStack.getTopElem()); lStack.stackClear(); System.out.println("棧是否為空: " + lStack.isStackEmpty()); } }
- 輸出:
此時,鏈棧中的元素為: 10 9 8 7 6 5 4 3 2 1 棧頂元素為: 10 棧是否為空: false 此時,鏈棧中的元素為: 9 8 7 6 5 4 3 2 1 棧頂元素為: 9 棧是否為空: true