1. 程式人生 > >順序棧的棧基本操作(C語言版)

順序棧的棧基本操作(C語言版)

its 如果能 百度 eal 否則 字節 總結 空間大小 存儲

  由於現在只學了C語言所以就寫這個C語言版的棧的基本操作

這裏說一下 :網上和書上都有這種寫法 int InitStack(SqStack &p)

&p是取地址 但是這種用法好像C並不支持 ,C++才支持,所以用

C語言寫就需要使用指針

代碼如下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #define STACK_INIT_SIZE 100//儲存空間初始分配量
  4 #define STACKINCREMENT  10//存儲空間分配增量
  5 #define OK 0
  6 #define
ERROR 1 7 typedef int StackType; //棧元素類型 8 9 typedef struct { 10 StackType *base; //在構造之前和銷毀之後,base的值為NULL 11 StackType *top; //棧頂指針 12 int stacksize; //當前已分配的存儲空間,以元素為單位 13 }SqStack; //順序棧 14 15 //棧的初始化 16 int InitStack(SqStack *p) { 17 18 19 p->base = (StackType*)malloc
(STACK_INIT_SIZE * sizeof(StackType)); 20 if (p->base == NULL) return ERROR; //內存分配失敗 21 p->top = p->base; //棧頂與棧底相同表示一個空棧 22 p->stacksize = STACK_INIT_SIZE; 23 return OK; 24 25 } 26 //判斷棧是否為空 27 int EmptyStack(SqStack *p) { 28 //若為空棧 則返回OK,否則返回ERROR 29 if
(p->top == p->base) return OK; 30 else return ERROR; 31 } 32 //順序棧的壓入 33 int Push(SqStack *p,StackType e) { 34 //插入元素e為新的棧頂元素 35 if ((p->top - p->base)>= p->stacksize) //棧滿,追加儲存空間 36 { 37 p->base = (StackType*)realloc(p->base, (p->stacksize + STACKINCREMENT) * sizeof(StackType)); 38 if (p->base == NULL) return ERROR;// 儲存空間分配失敗 39 p->top = p->base + p->stacksize; 40 41 /*p->top = p->base + p->stacksize;這句是有必要加上的 42 這一個問題的關鍵在於 realloc 是怎麽實現的,有兩種情況: 43 如果有足夠空間用於擴大mem_address指向的內存塊,則分配額外內存,並返回mem_address。 44 這裏說的是“擴大”,我們知道,realloc是從堆上分配內存的,當擴大一塊內存空間時, 45 realloc()試圖直接從堆上現存的數據後面的那些字節中獲得附加的字節,如果能夠滿足,自然天下太平。 46 也就是說,如果原先的內存大小後面還有足夠的空閑空間用來分配,加上原來的空間大小= newsize。 47 那麽就ok。得到的是一塊連續的內存。 48 如果原先的內存大小後面沒有足夠的空閑空間用來分配,那麽從堆中另外找一塊newsize大小的內存。 49 並把原來大小內存空間中的內容復制到newsize中。返回新的mem_address指針。(數據被移動了)。老塊被放回堆上。 50 如果是第二種情況的話,s->top 就不是原來的 top 了--百度百科*/ 51 52 p->stacksize += STACKINCREMENT; 53 } 54 *(p->top) = e; 55 (p->top)++; 56 return OK; 57 } 58 // 順序棧的彈出 59 int Pop(SqStack *p,StackType *e) { 60 //若棧不空,則刪除p的棧頂元素,用e返回其值 61 if (p->top == p->base) return ERROR; 62 --(p->top); 63 *e = *(p->top); 64 return OK; 65 66 67 } 68 //順序棧的銷毀 69 int DestroyStack(SqStack *p) { 70 //釋放棧底空間並置空 71 free(p->base); 72 p->base = NULL; 73 p->top = NULL; 74 p->stacksize = 0; 75 76 return OK; 77 } 78 //將順序棧置空 棧還是存在的,棧中的元素也存在,如果有棧中元素的地址任然能調用 79 int ClearStack(SqStack *p) { 80 p->top= p->base; 81 return OK; 82 } 83 //返回順序棧的元素個數 84 int StackLength(SqStack p) { 85 //棧頂指針減去棧底指針等於長度,因為棧頂指針指向當前棧頂元素的下一個位置 86 return p.top - p.base; 87 } 88 //返回順序棧的棧頂元素 89 int GetTop(SqStack *p, StackType *e) { 90 //若棧不為空,則用e返回p的棧頂元素 91 if (p->top > p->base) { 92 *e = *(p->top - 1); return OK; 93 } 94 else return ERROR; 95 } 96 //從棧頂到棧底對每個元素調用某個函數 97 int StackTraverse(SqStack p,void (*pfun)(StackType)/*函數指針*/){ 98 //從棧底到棧頂依次對棧中的每個元素調用函數pfun() 99 while (p.top > p.base) 100 pfun(*(p.base)++); //先調用後遞增 101 printf("\n"); 102 return OK; 103 } 104 //打印棧中元素 105 void print(StackType stack) { 106 printf("%d\n", stack); 107 108 } 109 //測試棧的各種操作 110 int main() { 111 int n,i; 112 StackType *e,a; 113 SqStack *pstack,stack; 114 pstack = &stack; 115 e=(StackType*)malloc(sizeof(StackType)); //為指針e分配內存地址 116 InitStack(pstack); //初始化棧 117 118 if (EmptyStack(pstack) == 0) printf("-------棧為空-------\n"); 119 printf("請輸入棧的元素個數:"); 120 scanf("%d", &n); 121 for (i = 0; i < n; i++) 122 { 123 scanf("%d", &a); 124 Push(pstack, a); 125 } 126 if (EmptyStack(pstack) == 1) printf("-------棧不為空-----\n"); 127 128 printf("棧的長度為:%d\n", StackLength(stack)); 129 printf("--------------------\n"); 130 printf("請輸入一個入棧元素:"); 131 scanf("%d", &a); 132 Push(pstack, a); 133 printf("--------------------\n"); 134 printf("棧中的元素個數為:%d\n", StackLength(stack)); 135 printf("--------------------\n"); 136 GetTop(pstack, e); 137 printf("棧頂元素為:%d\n", *e); 138 printf("--------------------\n"); 139 printf("打印棧中的元素:\n"); 140 StackTraverse(stack, print); 141 printf("---彈出棧頂元素---\n"); 142 Pop(pstack, e); 143 printf("彈出的棧頂元素為:%d\n", *e); 144 printf("--------------------\n"); 145 GetTop(pstack, e); 146 printf("棧頂元素為:%d\n", *e); 147 printf("--------------------\n"); 148 printf("打印棧中的元素:\n"); 149 StackTraverse(stack, print); 150 printf("--------------------\n"); 151 152 printf("----------清空棧-------\n"); 153 if (ClearStack(pstack) == 0) printf("已清空棧\n"); 154 155 printf("----------銷毀棧-------\n"); 156 if (DestroyStack(pstack) == 0) printf("已銷毀棧\n"); 157 return 0; 158 159 }

  寫這些代碼的時候還是遇到了一些問題 在這裏總結一下:

第一 對於指針的使用要慎重 因為它傳遞進函數會改變原始數據,所以對於不需要改變

指針指向的值的情況就不要使用指針。

第二 對於指針的使用 如下定義 int *e=NULL; *e=3;

看著好像沒有問題 編譯也沒問題 但是運行程序就出錯

為什麽? 沒有為指針e分配內存地址 所以引用肯定錯誤啊(我這個逗逼錯誤-_-)

正確的用法應該是 int *e=NULL;e=(int*)malloc(sizeof(int)); *e=3;

我之前都是 int *e,a; e=&a; e=3; 這種用法 所以......


順序棧的棧基本操作(C語言版)