#include <stdio.h> #include <malloc.h> #define TRUE 1 #define OK 1 #define ERROR 0 #define FALSE 0 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 typedef int Status; typedef int SElemType; struct SqStack { SElemType *base; SElemType *top; int stacksize; }; Status InitStack(SqStack &S) { S.base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!S.base) return ERROR; S.top = S.base; S.stacksize = STACK_INIT_SIZE; return OK; } Status Push(SqStack &S,SElemType e) { if(S.top-S.base>=S.stacksize) { S.base = (SElemType*)realloc(S.base,((S.stacksize + STACKINCREMENT)*sizeof(SElemType))); if(!S.base) return ERROR; S.top = S.base + S.stacksize;
/*
這一個問題的關鍵在於 realloc 是怎么實現的,有兩種情況:
-
-
-
如果有足夠空間用於擴大mem_address指向的內存塊,則分配額外內存,並返回mem_address。這里說的是“擴大”,我們知道,realloc是從堆上分配內存的,當擴大一塊內存空間時, realloc()試圖直接從堆上現存的數據后面的那些字節中獲得附加的字節,如果能夠滿足,自然天下太平。也就是說,如果原先的內存大小后面還有足夠的空閑空間用來分配,加上原來的空間大小= newsize。那么就ok。得到的是一塊連續的內存。
-
如果原先的內存大小后面沒有足夠的空閑空間用來分配,那么從堆中另外找一塊newsize大小的內存。並把原來大小內存空間中的內容復制到newsize中。返回新的mem_address指針。(數據被移動了)。老塊被放回堆上。
-
-
如果是第二種情況的話,s->top 就不是原來的 top 了。。
所以結論就是,很有必要。
*/
S.stacksize += STACKINCREMENT; } *S.top++ = e; return OK; } Status Pop(SqStack &S,SElemType &e) { if(S.top == S.base) return ERROR; e = *--S.top; return OK; } Status GetTop(SqStack &S,SElemType &e) { if(S.top == S.base) return ERROR; e = *(S.top - 1); return OK; } int StackLength(SqStack S) { int count = 0; int i; while(S.top != S.base) { count++; S.top--; } return count; // 返回棧S的元素個數 // 請補全代碼 } Status StackTraverse(SqStack S) { // 從棧頂到棧底依次輸出棧中的每個元素 SElemType *p = (SElemType *)malloc(sizeof(SElemType)); p = S.top; //請填空 if(S.top == S.base)printf("The Stack is Empty!"); //請填空 else { printf("The Stack is: "); p--; while(p >= S.base) //請填空 { printf("%d ", *p); p--; //請填空 } } printf("\n"); return OK; } int main() { int a; SqStack S; SElemType x, e; if(InitStack(S)) // 判斷順序表是否創建成功,請填空 { printf("A Stack Has Created.\n"); } while(1) { printf("1:Push \n2:Pop \n3:Get the Top \n4:Return the Length of the Stack\n5:Load the Stack\n0:Exit\nPlease choose:\n"); scanf("%d",&a); switch(a) { case 1: scanf("%d", &x); if(!Push(S,x)) printf("Push Error!\n"); // 判斷Push是否合法,請填空 else printf("The Element %d is Successfully Pushed!\n", x); break; case 2: if(!Pop(S,e)) printf("Pop Error!\n"); // 判斷Pop是否合法,請填空 else printf("The Element %d is Successfully Poped!\n", e); break; case 3: if(!GetTop(S,e))printf("Get Top Error!\n"); // 判斷Get Top是否合法,請填空 else printf("The Top Element is %d!\n", e); break; case 4: printf("The Length of the Stack is %d!\n",StackLength(S)); //請填空 break; case 5: StackTraverse(S); //請填空 break; case 0: return 1; } } }