顺序栈(含有栈顶指针,栈底指针)的实现以及编写过程中的一些疑惑的解决

参考文献:数据结构(c语言版)---严蔚敏p44----->p47

代码如下:

#include//malloc realloc
#include//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<<"申请空间失败"<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<<"申请空间失败"<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<<"栈已空"<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<<"栈空"<top - 1);/*问题三:使用*(--s->top)不是等价么?????*/
	return true;		
}
/*主函数*/
int main()
{
	SqStack s;
	InitStack(&s);

	int n;
	cout<<"请输入要转化数值:"<>n;

	while(n)
	{
		Push(&s,n%2);
		n /= 2;
	}

	int e;
	while(!StackEmpty(&s))
	{
		Pop(&s,&e);
		cout<
问题一:为何要修改栈顶指针?

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<<"申请空间失败"<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<<"栈空"<top - 1);/*问题三:使用*(--s->top)不是等价么?????*/
	return true;		
}
使用(s->top - 1)与使用-- s->top的区别在于:

     1)s->top - 1 执行之后,s->top的值不发生改变

     2)--s->top   执行之后,s->top的发生改变,减了个一

获得栈顶元素的同时,不应该改变栈顶指针的指向,所以不是等价的


你可能感兴趣的:(数据结构)