鏈棧的基本操作(C語言)


  棧的鏈式儲存結構稱為鏈棧。鏈棧的節點類型與鏈式線性表的節點類型

定義相同,不同的是它是僅在表頭進行操作的單鏈表。鏈棧通常用不帶頭節

點的單鏈表來實現,棧頂指針就是鏈表的頭指針 ,如圖所示:

  

  代碼如下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 #define OK 1
  5 #define ERROR 0
  6 typedef int SElemType;
  7 //棧的鏈式儲存結構
  8 typedef struct SNode {
  9     SElemType data; //數據域
 10     struct SNode *next; //指針域
 11 
 12 }SNODE, *PSNODE;
 13 //棧頂節點
 14 typedef struct
 15 {
 16     PSNODE top; //棧頂指針
 17     int count;  //棧的長度 
 18     
 19 }LinkStack;
 20 
 21 //初始化棧頂節點
 22 int Init_LS(LinkStack *s) {
 23     s->top = (PSNODE)malloc(sizeof(SNODE));
 24         if (!s->top)
 25             return ERROR;
 26     
 27         s->top = NULL;
 28         s->count = 0;
 29         return OK;
 30 }
 31 //判斷棧是否為空 
 32 int Is_Empty(LinkStack *s) {
 33     if (s->top == NULL)
 34     {
 35         printf("棧為空\n");
 36         return OK;
 37     }
 38         
 39     else {
 40         printf("棧不為空\n");
 41         return ERROR;
 42     }
 43 }
 44 //遍歷棧
 45 int Traverse_LS(LinkStack *s) {
 46     int i;
 47     if (Is_Empty(s) == OK) return ERROR;
 48     PSNODE p = s->top;
 49     for(i=s->count;i>0;i--)
 50     {
 51         
 52         printf("%d ", p->data);
 53         p = p->next;
 54     }
 55     printf("\n");
 56     return OK;
 57 }
 58 //鏈棧元素入棧
 59 int Push_LS(LinkStack *s, SElemType e) {
 60        
 61     PSNODE p = (PSNODE)malloc(sizeof(SNODE));
 62     if (!p)  return ERROR;
 63         p->data = e;
 64         p->next = s->top;   //新結點指向棧頂指針指向的地址 
 65         s->top = p;         //更新棧頂指針 
 66         s->count++;      // 節點增加1
 67     
 68         return OK;
 69 
 70 }
 71 // 獲取棧頂元素 
 72 int GetTop(LinkStack *s, SElemType *e) {
 73     if (Is_Empty(s) == OK) return ERROR;
 74     *e = s->top->data;
 75     return OK;
 76 }
 77 //鏈棧元素出棧
 78 int Pop_LS(LinkStack *s, SElemType *e) {
 79     if (Is_Empty(s) == OK) return ERROR;
 80         
 81     PSNODE temp = s->top;
 82     *e = temp->data;
 83     s->top = temp->next;
 84     s->count--;
 85     free(temp);
 86     return OK;
 87 }
 88 //銷毀棧
 89 int Destroy_LS(LinkStack *s) {
 90     PSNODE p,q=NULL;
 91     if(Is_Empty(s)==OK) return ERROR;
 92     p = s->top;
 93     for (int i = s->count; i > 0; i--)
 94     {
 95         q = p->next;
 96         free(p);
 97         p = q;
 98     }
 99     s->count = 0; 
100     return OK;
101 }
102 
103 int main() {
104     LinkStack s,*ps;
105     SElemType a, *e;
106     e = (SElemType*)malloc(sizeof(SElemType));
107     ps = &s;
108     Init_LS(ps);
109     int n;
110     Is_Empty(ps);
111     printf("請輸入入棧元素的個數:");
112     scanf("%d", &n);
113     for(int i=0;i<n;i++)
114     {
115         scanf("%d", &a);
116         Push_LS(ps, a);
117     }
118     Traverse_LS(ps);
119     Pop_LS(ps, e);
120     printf("彈出的元素為%d\n", *e);
121     Traverse_LS(ps);
122     GetTop(ps, e);
123     printf("棧頂元素為%d\n", *e);
124     if(Destroy_LS(ps)==OK) printf("棧銷毀成功!");
125 
126     return 0;
127 }

  我寫的這個鏈棧的代碼 稍微修改了一點 --把棧頂指針與count 組成一個結構體

count用來儲存鏈棧的長度。如果鏈棧的長度很長而且經常需要返回長度 一個一個

算的話顯得特別費時間;而使用count要方便的多 。

  如果我們要把兩個鏈棧合並,必然需要其中一個的棧底地址

而且如果這個鏈棧很大,我們要從棧頂開始尋找棧底地址 很麻煩吧

但是我們在LinkStack  中增加一個 PSNODE bottom指針,在入棧函數中

根據count來給bottom賦值。這樣棧底地址就有了。

  所以,數據結構的一些細節上的東西不是一成不變的,而是可以根據具體

的問題修改。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM