参考文献:数据结构(c语言版)---严蔚敏p44----->p47
代码如下:
#include<stdlib.h>//malloc realloc #include<iostream>//cin cout using namespace std; typedef int ElemType;/*元素类型*/ #define STACK_INIT_SIZE 100 /*栈存储空间初始化容量*/ #define STACKINCREMENT 10 /*栈存储空间每次的增量*/ /*管理栈的结构体*/ typedef struct { ElemType *base; /*栈底指针*/ ElemType *top; /*栈顶指针*/ int StackSize; /*栈的容量*/ }SqStack; /*初始化栈*/ bool InitStack(SqStack *s) { s->base = (ElemType *)malloc(sizeof(ElemType)*STACK_INIT_SIZE); if(!(s->base))/*判断申请空间是否成功,这一步不可省略*/ { cout<<"申请空间失败"<<endl; return false; } s->top = s->base;/*栈空时,栈顶和栈底重合*/ s->StackSize = STACK_INIT_SIZE; return true; } /*入栈*/ bool Push(SqStack *s,ElemType e) { if(s->top - s->base >= s->StackSize)/*判断栈是否已满,如已满,动态增加容量*/ { s->base = (ElemType *)realloc(s->base,sizeof(ElemType)*(s->StackSize+STACKINCREMENT)); if(!(s->base)) { cout<<"申请空间失败"<<endl; return false; } s->top = s->base + s->StackSize;/*问题一:为何要修改栈顶指针?????*/ s->StackSize += STACKINCREMENT; } *(s->top++) = e; return true; } /*出栈*/ bool Pop(SqStack *s,ElemType *e) { if(s->top == s->base) { cout<<"栈已空"<<endl; return false; } *e = *(--s->top);/*栈顶指针始终指向栈中最后一个元素的下一个元素,所以要先减一*/ return true; } /*清空栈*/ void ClearStack(SqStack *s) { s->top = s->base; } /*销毁栈*/ void DestoryStack(SqStack *s) { free(s->base);/*释放在栈上申请的空间*/ s->base = s->top = NULL;/*将栈顶指针和栈底指针赋空,防止被无意解引用*/ } /*判断栈是否为空*/ bool StackEmpty(SqStack *s) { return s->base == s->top; } /*栈的长度,即栈中元素的个数*/ int StackLength(SqStack *s) { return s->top - s->base;/*问题二:地址相减得到什么??????*/ } /*获得栈顶元素*/ bool GetTop(SqStack *s,ElemType *e) { if(StackEmpty(s)) { cout<<"栈空"<<endl; return false; } *e = *(s->top - 1);/*问题三:使用*(--s->top)不是等价么?????*/ return true; } /*主函数*/ int main() { SqStack s; InitStack(&s); int n; cout<<"请输入要转化数值:"<<endl; cin>>n; while(n) { Push(&s,n%2); n /= 2; } int e; while(!StackEmpty(&s)) { Pop(&s,&e); cout<<e<<" "; } cout<<endl; DestoryStack(&s); return 0; }问题一:为何要修改栈顶指针?
bool Push(SqStack *s,ElemType e) { if(s->top - s->base >= s->StackSize)/*判断栈是否已满,如已满,动态增加容量*/ { s->base = (ElemType *)realloc(s->base,sizeof(ElemType)*(s->StackSize+STACKINCREMENT)); if(!(s->base)) { cout<<"申请空间失败"<<endl; return false; } s->top = s->base + s->StackSize;/*问题一:为何要修改栈顶指针?????*/ s->StackSize += STACKINCREMENT; } *(s->top++) = e; return true; }这与realloc的实现有关,先看一下msdn的一段话:
1、如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address
这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。那么就ok。得到的是一块连续的内存。
2、如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。
并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。(数据被移动了)。
老块被放回堆上。
即:realloc函数执行完之后,存储空间可能已经改变,s->top所指的空间或许已经被释放(第二种情况),所以要修改s->top的指向!!!
问题二:指针相减,结果是什么:
/*栈的长度,即栈中元素的个数*/ int StackLength(SqStack *s) { return s->top - s->base;/*问题二:地址相减得到什么??????*/ }当两个指针指向同一个数组时:指针相减得到的是两地址之间元素的个数
问题三:(s->top - 1)与(-- s->top)是否等价
/*获得栈顶元素*/ bool GetTop(SqStack *s,ElemType *e) { if(StackEmpty(s)) { cout<<"栈空"<<endl; return false; } *e = *(s->top - 1);/*问题三:使用*(--s->top)不是等价么?????*/ return true; }使用(s->top - 1)与使用-- s->top的区别在于:
1)s->top - 1 执行之后,s->top的值不发生改变
2)--s->top 执行之后,s->top的发生改变,减了个一
获得栈顶元素的同时,不应该改变栈顶指针的指向,所以不是等价的
顺序栈(含有栈顶指针,栈底指针)的实现以及编写过程中的一些疑惑的解决
原文地址:http://blog.csdn.net/zongyinhu/article/details/46275231