代码改变世界

数据结构学习之栈

2016-04-20 19:14  三戒1993  阅读(182)  评论(0编辑  收藏  举报

本例主要是实现一个顺序栈;其它的啥也不说;直接上代码:

/*
或许这就是指针的魅力;也是指针折磨人的地方。指针可以直接对内存进行操作,非常强大;它操作的对象是地址;
是计算机最本质的东西;你在操作的时候是比较爽了;但是当你在程序中“不小心”改变了指针变量的值;当你再次
访问时;就会出现一些莫名其妙的错误(通常是访问了不该访问的内存,因为指针的内容变了;但是程序的逻辑是
没有任何错误的;你就会变得特别崩溃;本例具体的错误如下所示);

*/

#include<stdio.h>
#include<stdlib.h>

#define STACK_INIT_SIZE 10
#define STACK_INCREASE 2

typedef struct STACK
{
int *pBase;
int *pTop;
int size;
} Stack;


void InitStack(Stack *);
void DestroyStack(Stack *);
void ClearStack(Stack *);
int Empty(Stack *);
int LengthStack(Stack *);
int GetTop(Stack *, int *);
void Push(Stack *, int);
int Pop(Stack *, int *);
void TraverseStack(Stack *);


int main(void)
{
int i;
int e, e0;
Stack S;

InitStack(&S);

for (i=0; i<10; i++)
{
Push(&S, i);
}
/*因为在程序中有了这句;所以我在进行弹出操作时怎样也不对;打印出的e值总是垃圾数据;折腾了许久
才知道:在遍历程序中我改变了栈底指针的值;而在弹出操作中我又使用到了栈底指针;所以才会出现错误
因为是指针;在程序中某一处改变了它的值;那么在再次访问时就会影响;所以本程序写的并不好*/
TraverseStack(&S);
for (i=0; i<6; i++)
{
if (Pop(&S, &e) == 1)
{
printf("pop success; the data is %d \n", e);
}
else
printf("pop failed !\n");
}
if (GetTop(&S, &e0) == 1)
{
printf("the top element is %d \n", e0);
}
else
printf(" may be stack is empty;may be code exit error.\n");

return 0;
}


/*和线性结构一样,这样便构造了一个线性表;也就是一个结构体,这个结构体保存了这个线性表的基本信息*/
void InitStack(Stack * S)
{
S->pBase = (int *)malloc(sizeof(int)*STACK_INIT_SIZE);
if (S->pBase == NULL)
{
printf("alloc memery is failed! \n");
exit(-1);
}
S->pTop = S->pBase;
S->size = STACK_INIT_SIZE;
}

void DestroyStack(Stack * S)
{
free(S->pBase);
S->pBase = NULL;
S->pTop = NULL;
S->size = 0;
}

void ClearStack(Stack *S)
{
S->pTop = S->pBase;
}

int Empty(Stack *S)
{
if (S->pBase == S->pTop)
return 1;
else
return 0;
}

int LengthStack(Stack * S)
{
return S->pTop - S->pBase;
}
/*该段代码不好;因为改变了栈顶指针的值;如果再次被调用;则会出现错误*/
int GetTop(Stack *S, int *element)
{
int *p = S->pTop;

if (p > S->pBase)
{
*element = *(p - 1);
return 1;
}
else
return 0;
}

void Push(Stack *S, int element)
{
if (S->pTop - S->pBase == S->size)//当栈满是一种情况
{
S->pBase = (int *)realloc(S->pBase, (STACK_INIT_SIZE + STACK_INCREASE) * sizeof(int));
if (S->pBase == NULL)
{
printf("alloc memery is failed! \n");
exit(-1);
}
else
{
S->pTop = S->pBase + S->size;
S->size += STACK_INCREASE;
}
}
else //栈不满的情况
{
*(S->pTop) = element;
S->pTop ++ ;
}
}

int Pop(Stack *S, int *element)
{
if (S->pBase == S->pTop)
return 0;

-- S->pTop;
*element = *(S->pTop);

return 1;
}

/*弹出元素总是不成功,是不是因为在调用TraverseStack()函数时,将栈底指针改变了;所以才会造成各种错误*/
void TraverseStack(Stack *S)
{
int *p = NULL;//由错误提醒我们:在操作时,不要直接对全局变量操作;给它一个初值再进行操作;可能效好
p = S->pBase;

while (p < S->pTop)
{
printf("%d ", *p);
p++;
}
printf("\n");
}