顺序栈和链栈的各种操作

 

一.先说顺序栈

/**********************************************************
顺序栈的各种操作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的值。

看一下运行结果截图:

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



 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值