棧是一種線性的數據結構,它的操作限定在了棧頂,即只能夠在棧頂進行數據的插入,刪除以及其它各種操作;棧的操作特性為先進后出,下面給出
一張圖來說明一下棧的入棧操作。
通過這個圖,發現入棧都是在棧頂進行的,top等於base表示此棧為空棧。上面的入棧順序為A、B、C、D,在出棧的時候由於只能在棧頂操作,因此
在出棧的時候,順序就反過來了;所以棧的操作特性就是先進后出。
另外,棧分為順序棧和鏈棧,在這里呢,我是用順序棧來實現的,個人認為順棧的實現更簡潔方便。另外雖然c++STL標准庫里封裝了棧結構,並且使用起來
也很方便,但是還是很有必要了解一下它的實現原理的。下面代碼詳細的寫了棧的常見操作,並且測試過了。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<malloc.h> 4 #define MAXSIZE 100 5 typedef struct 6 { 7 int *top; //始終指向棧頂的空位置 8 int *base; //棧底 9 int stacksize; //當前棧的大小 10 }sqstack; 11 12 int Initstack(sqstack *s) 13 { 14 s->base=(int *)malloc(sizeof(int)*MAXSIZE); //為堆棧開辟空間 15 if(!s->base) 16 { 17 printf("存儲分配失敗"); 18 exit(-1); 19 } 20 s->top=s->base; //空棧的話top和base指向同一位置 21 s->stacksize= MAXSIZE; 22 return 1; 23 } 24 int push(sqstack *s,int e) //入棧 25 { 26 if(s->top-s->base==MAXSIZE) 27 { 28 printf("堆棧已滿,無法入棧\n"); 29 exit(-1); 30 } 31 *s->top=e; 32 s->top++; //入棧后棧頂指針top指向下一個空位置 33 //*(s->top)++=e; 34 return 1; 35 } 36 int pop(sqstack *s,int *e) //出棧 37 { 38 if(s->top==s->base) 39 { 40 printf("棧是空的,無法出棧"); 41 return 0; 42 } 43 s->top--; //因為top指向棧頂的下一個位置,是空的,所以要通過自減來指向棧頂元素 44 *e=*s->top; 45 return 1; 46 } 47 void printstack(sqstack s) //由於是打印堆棧,不需要修改原來堆棧的值,所以形參設為普通變量就行,不需要設成指針 48 { 49 int *p=s.top; 50 while(p>s.base) 51 { 52 p--; 53 printf("%d ",*p); 54 } 55 printf("\n"); 56 } 57 int Gettop(sqstack s,int *e) //獲取棧頂元素,不需要修改原來堆棧的值,所以形參設為普通變量就行,不需要設成指針 58 { 59 if(s.top==s.base) 60 return 0; 61 s.top--; 62 *e=*s.top; 63 return 1; 64 } 65 int stacklength(sqstack s) //獲取棧的長度 66 { 67 if(s.top==s.base) 68 return 0; 69 else 70 return(s.top-s.base); 71 } 72 int isempty(sqstack s) //判斷堆棧是否為空 73 { 74 if(s.top==s.base) //空棧返回1,非空返回0 75 return 1; 76 else 77 return 0; 78 } 79 void clear(sqstack *s) //清空堆棧 80 { 81 s->top=s->base; 82 } 83 int main() 84 { 85 int e; 86 char ch; 87 sqstack s; 88 Initstack(&s); ///初始化堆棧 89 printf("輸入棧中的元素:\n"); 90 do{ 91 scanf("%d",&e); 92 push(&s,e); 93 }while((ch=getchar())!='\n'); 94 95 printf("棧中元素為:\n"); 96 printstack(s); 97 printf("棧的長度為:%d\n", stacklength(s)); 98 Gettop(s,&e); 99 printf("棧頂元素為:%d\n",e); 100 for(int i=1;i<=5;i++) 101 { 102 pop(&s,&e); 103 printf("第%d次出棧的元素為:%d\n",i,e); 104 } 105 printf("彈棧后棧中剩余元素為:"); 106 printstack(s); 107 printf("彈棧后棧的長度為:%d\n", stacklength(s)); 108 Gettop(s,&e); 109 printf("彈棧后棧頂元素為:%d\n",e); 110 printf("結果為1表示空棧,結果為0表示非空棧:%d\n",isempty(s)); 111 clear(&s); 112 printf("清空后棧的長度為:%d\n", stacklength(s)); 113 printf("結果為1表示空棧,結果為0表示非空棧:%d\n",isempty(s)); 114 return 0; 115 }
結果如下:
注意,由於棧是先進后出的,所以棧中數據的順序和輸入的數據順序是相反的。
2020-04-29 17:10:06