您的位置:首页 > 其它

顺序栈和链栈的各种操作

2011-10-08 00:06 232 查看
一.先说顺序栈

view
plainprint?

/**********************************************************

顺序栈的各种操作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;

}

二.再说链栈

view
plainprint?

/**********************************************************

链栈的各种操作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中

view
plainprint?

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中

view
plainprint?

int main()

{

//LinkStack *top=(LinkStack *)malloc(sizeof(LinkStack));

LinkStack *top=NULL;



InitStack(&top);



}//去掉上面的,不用给top赋实际地址了,在调用InitStack(&top)的

//时候传递top的地址过去就行了,改到InitStack里面来改变top的值。

看一下运行结果截图:



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

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