1. 程式人生 > >棧的鏈式存儲結構及應用(C、Java代碼)

棧的鏈式存儲結構及應用(C、Java代碼)

ops bubuko gif one get image ++ 我們 溢出

鏈式存儲結構最大的好處就是沒有空間的限制,可以通過指針指向將結點像以鏈的形式把結點鏈接,我們熟悉的線性表就有鏈式存儲結構。

當然,棧同樣有鏈式存儲結構,棧的鏈式存儲結構,簡稱鏈棧。

技術分享圖片

從圖片可以看到,和單鏈表很像,擁有一個頭指針top,又稱作棧頂指針,所以此時就不再需要單鏈表裏面的頭結點了。

對於鏈棧來說,基本不存在棧滿的情況,除非計算機內存已經沒有了可使用的空間,如果真的存在,那麽計算機系統已經面臨著即將死機崩潰的情況,而不是這個鏈棧是否溢出的問題了。

對於空棧來說,鏈表的定義是頭指針指向NULL,而鏈棧是top=NULL

鏈棧的結構定義:

 1 /*鏈棧的定義需要用到兩個結構體
*/ 2 typedef struct StackNode{ //單鏈表節點類型 3 int data; 4 StackNode* next; 5 6 }StrackNode; 7 typedef struct StackNode *LinkStackPtr; 8 9 typedef struct { // 10 11 LinkStackPtr top; //棧底指針 12 int count; 13 14 }LinkStact;

進棧操作

技術分享圖片

/*入棧*/
void
PushStack(LinkStact *s,int e){ //這邊棧應該傳地址 LinkStackPtr a =(StackNode*)malloc(sizeof(StackNode)); //新的節點 a->data = e; a->next = s->top; //把當前的棧頂元素賦值給新結點的直接後繼 s->top =a; /* 將新的結點s賦值給棧頂指針 */ s->count++; }

這裏重新回憶一下參數傳參的兩種方式:傳值、傳地址。

傳值:傳值無非就是實參拷貝傳遞給形參,單向傳遞(實參->形參),二者中間做了一個拷貝動作,即兩者的實際地址不同了,所以對任何一方的操作都不會影響到另一方。

傳地址:形參和實參是同一個變量,即使用相同的內存空間,二者有相同的地址,修改任意一方都將相互影響。

出棧操作

技術分享圖片

/*出棧,並返回棧頂元素*/
int PopStack(LinkStact *s){
    int top;
    LinkStackPtr p;
    p = s->top;      /* 將棧頂結點賦值給p */
    if(p ==NULL)
        return -1;
    top = p->data;
    s->top=s->top->next;  /* 使得棧頂指針下移一位,指向後一結點,即指向新的棧頂 */
    free(p);   //釋放內存
    s->count--;   //長度減一

    return top;
}

使用棧時確記要記得給棧初始化

1 /*初始化一個空棧*/
2 int InitStack(LinkStact *s){
3     s->top = (StackNode *)malloc(sizeof(StackNode));
4     if(!s->top)
5         return 0;
6     s->top=NULL;
7     s->count=0;
8     return 1;
9 }

遍歷棧操作

 1 /*遍歷棧*/
 2 void StackTraverse(LinkStact s){
 3     LinkStackPtr p;
 4     p=s.top;   //指針指向棧頂
 5     while(p)        //當棧不為空時
 6     {
 7         printf("%d ",p->data);
 8         p =p->next;
 9     }
10 }

清空棧操作

 1 /*清空棧*/
 2 void ClearStack(LinkStact *s){
 3 
 4     LinkStackPtr p,q;
 5     p = s->top;   //取棧頂
 6     while(p){
 7         q=p;
 8         p=p->next;
 9         free(q);
10     }
11     s->count=0;
12 }

其他的操作見代碼:

技術分享圖片
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 /*鏈棧的定義需要用到兩個結構體*/
  5 typedef struct StackNode{        //單鏈表節點類型
  6     int data;
  7     StackNode* next;
  8 
  9 }StrackNode;
 10 typedef struct StackNode *LinkStackPtr;
 11 
 12 typedef struct {    //
 13 
 14     LinkStackPtr top;   //棧底指針
 15     int count;          
 16 
 17 }LinkStact;
 18 
 19 /*初始化一個空棧*/
 20 int InitStack(LinkStact *s){
 21     s->top = (StackNode *)malloc(sizeof(StackNode));
 22     if(!s->top)
 23         return 0;
 24     s->top=NULL;
 25     s->count=0;
 26     return 1;
 27 }
 28 
 29 /*清空棧*/
 30 void ClearStack(LinkStact *s){
 31 
 32     LinkStackPtr p,q;
 33     p = s->top;   //取棧頂
 34     while(p){
 35         q=p;
 36         p=p->next;
 37         free(q);
 38     }
 39     s->count=0;
 40 }
 41 
 42 /*判斷是否為空棧,為空返回0,否則返回1*/
 43 int StackEmpty(LinkStact *s){
 44     if(s->count==0)
 45         return 1;
 46     else
 47         return 0;
 48 }
 49 
 50 /*入棧*/
 51 void PushStack(LinkStact *s,int e){   //這邊棧應該傳地址
 52 
 53     LinkStackPtr a =(StackNode*)malloc(sizeof(StackNode));   //新的節點
 54     a->data = e;
 55     a->next = s->top; //把當前的棧頂元素賦值給新結點的直接後繼
 56     s->top =a;  /* 將新的結點s賦值給棧頂指針 */
 57     s->count++;        
 58 }
 59 
 60 /*出棧,並返回棧頂元素*/
 61 int PopStack(LinkStact *s){
 62     int top;
 63     LinkStackPtr p;
 64     p = s->top;      /* 將棧頂結點賦值給p */
 65     if(p ==NULL)
 66         return -1;
 67     top = p->data;
 68     s->top=s->top->next;  /* 使得棧頂指針下移一位,指向後一結點,即指向新的棧頂 */
 69     free(p);   //釋放內存
 70     s->count--;   //長度減一
 71 
 72     return top;
 73 }
 74 
 75 /*返回棧的長度*/
 76 int StackLength(LinkStact s){
 77     return s.count;
 78 }
 79 
 80 /*若棧不為空,則返回棧頂元素*/
 81 int GetTop(LinkStact s){
 82     if(s.count == NULL)
 83         return 0;
 84     else
 85         return s.top->data;
 86 }
 87 
 88 /*遍歷棧*/
 89 void StackTraverse(LinkStact s){
 90     LinkStackPtr p;
 91     p=s.top;   //指針指向棧頂
 92     while(p)        //當棧不為空時
 93     {
 94         printf("%d ",p->data);
 95         p =p->next;
 96     }
 97 }
 98 
 99 int main(){
100     LinkStact s;
101     printf("進棧10個數據\n");
102     if(InitStack(&s)==1){
103         for(int i=1;i<=10;i++)
104             PushStack(&s,i);
105     }
106     StackTraverse(s);   //遍歷棧
107     printf("\n");
108     
109     printf("進棧後長度:%d\n",StackLength(s));
110 
111     printf("出棧,取棧頂元素,棧頂元素是 :%d",GetTop(s));
112     printf("\n");
113 
114     printf("棧是否為空? 1:0:%d\n",StackEmpty(&s));
115 
116     printf("出棧一個元素:%d\n",PopStack(&s));
117 
118     StackTraverse(s);
119 
120 
121     return 0;
122 }
View Code

技術分享圖片

另外附上Java代碼

棧的鏈式存儲結構及應用(C、Java代碼)