您的位置:首页 > 其它

顺序栈和链栈的各种操作

2011-08-19 09:28 399 查看
一.先说顺序栈

/**********************************************************
顺序栈的各种操作13-5-1.cpp
1.初始化栈
2.判断栈空
3.入栈
4.出栈
5.取栈顶元素
6.主函数测试以上功能
***********************************************************/
#include<stdio.h>
#include<stdlib.h>

#define MAX	1000
typedef struct
{
int data[MAX];
int top;
}SeStack;

void InitStack(SeStack *S)
{
S->top=-1;
}

int EmptyStack(SeStack *S)
{
return ((S->top==-1)?1:0);
}

int Push(SeStack *S, int x)
{
if(S->top==MAX-1)
{
printf("栈满!\n");
return 0;
}
S->data[++S->top]=x;
return 1;
}

int Pop(SeStack *S, int *x)
{
if(EmptyStack(S))
{
printf("栈空!\n");
return 0;
}
*x=S->data[S->top--];
return 1;
}

int GetTop(SeStack *S, int *x)
{
if(EmptyStack(S))
{
printf("栈空!\n");
return 0;
}
*x=S->data[S->top];
return 1;
}

int main()
{
SeStack *S=(SeStack *)malloc(sizeof(SeStack));
int n, x, fx, j;
InitStack(S);
printf("输入入栈元素个数:\n");
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
Push(S, i);
}

GetTop(S, &fx);
printf("栈顶元素:%d\n", fx);

printf("栈中元素:\n");
for(j=S->top; j>-1; j--)
{
printf("%3d",S->data[j]);
}

for(int i=1; i<=n; i++)
{
Pop(S, &x);
printf("\n出栈元素为:%d\n", x);
}
system("pause");
return 0;
}

二.再说链栈

/**********************************************************
链栈的各种操作13-5-2.cpp和13-5-3.cpp
1.初始化栈
2.判断栈空
3.入栈
4.出栈
5.取栈顶元素
6.主函数测试以上功能
***********************************************************/
#include<stdio.h>
#include<stdlib.h>

typedef struct Lnode
{
int data;
struct Lnode *next;
}LinkList;
typedef LinkList LinkStack;

void  InitStack(LinkStack *top)
{
/*
top=(LinkStack *)malloc(sizeof(LinkStack));//(1)
if(top==NULL)
{
printf("分配空间失败!\n");
return 0;
}
*/
//printf("(InitStack)top addr:%x\n", top);
top->next=NULL;
//return 1;
}

int EmptyStack(LinkStack *top)
{
return ((top->next==NULL)?1:0);
}

int Push(LinkStack *top, int x)
{
LinkStack *s=(LinkStack *)malloc(sizeof(LinkStack));
if(s==NULL)
{
printf("分配空间失败!\n");
return 0;
}
s->data=x;
s->next=top->next;
top->next=s;
//printf("(Push)top addr:%x\n", top);
return 1;
}

int Pop(LinkStack *top, int *x)
{
LinkStack *p;
if(EmptyStack(top))
{
printf("栈空!\n");
return 0;
}
*x=top->next->data;
p=top->next;
top->next=p->next;
//printf("(Pop)top addr:%x\n", top);
free(p);
return 1;
}

int GetTop(LinkStack *top, int *x)
{
if(EmptyStack(top))
{
printf("栈空!\n");
return 0;
}
*x=top->next->data;
return 1;
}

int main()
{
LinkStack *top=(LinkStack *)malloc(sizeof(LinkStack));
//printf("(main)top addr:%x\n", top);
LinkStack *p;
int n, x, fx;

InitStack(top);

printf("输入入栈元素个数n:\n");
scanf("%d", &n);
for(int i=1; i<=n; i++)
{
Push(top, i);
}

GetTop(top, &fx);
printf("栈顶元素:%d\n", fx);
printf("栈中元素:\n");
for(p=top->next; p!=NULL; p=p->next)//(2)
{
printf("%3d", p->data);
}
for(int i=1; i<=n; i++)
{
Pop(top, &x);
printf("\n出栈元素为:%d\n", x);
}
system("pause");
return 0;
}
/*************************************************************************************
注意:(1)注意这段注释掉的代码,我习惯性的按照链队列里面初始化队列的方式来初始化
链栈,结果导致运行(2)处,发生地质访问错误。仔细分析一下:(2)处的p移动到最后一个
节点的时候,再往后移动一个就出问题了。按理说最后一个节点的next应该是NULL,看
InitStack函数,确实应该在一开始就给top->next=NULL,但是我在InitStack函数里面却
又申请了一个内存空间,实际上就是给top又赋了一个新的地址,相当于传个参数(指针top)
进去又在函数里面改变了它的地址(给to赋了一个新地址),但是根据函数改变参数的机制,
只有使用二重指针做参数或者传递引用的时候,才能实际的改变参数。如果仅传一个一维指
针,只能改变指针里存的值,不能改变指针本身。这个和p65页面试题很像。可以看验证
截图。main中开辟的空间的首地址是x714e38赋给top,IintStack函数中又给top一个新地
址x714e80,但是IintStack结束之后,到了Push, Pop函数,地址皆为x714e38,和main
中的一样。也就验证了地址在InitStack结束之后根本木有改变。既然这样,在InitStack中给
top->next赋值为NULL,InitStack结束之后,top还是x714e38,这个top的next根本不知
道是什么,所以Push到最后一个的时候,最后一个元素的next就不知道是什么了,因为是由
top->next觉定的,所以也就发生了内存错误。所以再说一点就是建立栈操作时候,想在main函数中给top赋个NULL,然后在Init中开辟空间的,是不行了,要么在主函数中开辟空间给指针赋值,然后到init中直接传过去,注意,通过传参,在别的函数体力就改变不了指针值了。如果习惯在主函数中不管,赋值的活交给Init函数的话,就是用二重指针方式了。
***************************************************************************************/


先看验证注释(1)的运行结果截图



如果按照之前说的,将Init函数改成传二重指针的方式,在main里面仅仅给top=NULL,z Init里面再给top换个值,也就是开辟一段内存。这样就可以了,后面的(2)就可以正常运行了。
具体改动:
1.InitStack中
int  InitStack(LinkStack **top)
{

*top=(LinkStack *)malloc(sizeof(LinkStack));//(1)
if(*top==NULL)
{
printf("分配空间失败!\n");
return 0;
}
printf("(InitStack)top addr:%x\n", *top);
(*top)->next=NULL;
return 1;
}

2.main中
int main()
{
//LinkStack *top=(LinkStack *)malloc(sizeof(LinkStack));
LinkStack *top=NULL;
…
InitStack(&top);
…
}//去掉上面的,不用给top赋实际地址了,在调用InitStack(&top)的
//时候传递top的地址过去就行了,改到InitStack里面来改变top的值。

看一下运行结果截图:



最后看正常情况下程序的运行结果的图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: