《数据结构》堆栈2019/09/05

堆栈

栈是一种特殊的线性表,具有LIFO(LAST IN FIRST OUT)的性质,栈或许是除了数组之外应用最广的数据结构了。许多操作都需要借助栈来实现:浏览网站的“后退”键;WORD、PS中的撤销(CTRL+Z)等等——限定在表尾进行插入(入栈)、删除(出栈)操作的线性表。

堆栈的顺序存储实现

定义:

typedef int Position;
typedef struct SNode * PtrToSNode;
struct SNode {
ElementType *Data;
Position Top;
int MaxSize;
};
typedef PtrToSNode Stack;

在栈的定义中,不理解的地方在于为什么不直接用
Data[MaxSize]
这样的格式来直接定义栈中的数据区,而要用如上所示的首地址来表达数组。

2020/02/25编辑:Data[MaxSize]在ANSI C的标准中不被允许,原因是变量名不能用在数组的定义中(即Maxsize不能用在方括号中)。

自然的另一种定义方式:

#define MaxSize
typedef int Position;
typedef struct SNode * PtrToSNode;
struct SNode{
ElementType Data[MaxSize]
Position Top;
};
typedef struct PtrToSNode Stack;

数组长度由MaxSize决定,在开头由用户自定义。

初始化

//在第一种定义前提下,此初始化可以申请动态数组,或许这就是第一种定义方式的用意所在吧。
Stack CreateStack(int MaxSize)
{
	Stack S=(Stack)malloc(sizeof(struct SNode));
	S->Data=(ElementType*)malloc(MaxSize*sizeof(ElementType));/*此操作是申请动态数组*/
	S->Top=-1;
	S->MaxSize=MaxSize;
	return S;
}

入栈(PUSH)

在入栈之前首先要判断栈区是否已满,如果不满,把Top+1,再将新元素放入Data数组的Top位置。

bool IsFull(Stack S)
{
return(S->Top==MaxSize-1);
}

bool Push(Stack S,ElementType X)
{	
	if(IsFull(Stack S)){
		printf("堆栈已满");
		return false;
	}
	else{
	(S->Top)=(S->TOP)+1;
	S->Data[(S->Top)]=X;
	return true;
	}
}


出栈(POP)

和入栈一样,在执行出栈操作之前首先要判断栈区是否为空,若不空,可以直接让程序返回Data[Top],再将Top-1,否则返回一个错误标志,这个值必须是正常的栈元素数据不可能取到的值。

bool IsEmpty(Stack S)
{
	return (S->Top==-1);
}

ElementType Pop(Stack S)
{
	if(IsEmpty(Stack S))
	{
		printf("堆栈空了");
		return ERROR;
	}
	else {	//以下语句可以用:return (S->Data[(S->Top)--]);  代替。
		ElementType s=S->Data[(S->Top)];
		(S->Top)=(S->Top)-1;
		return s;   
	}
}

用一个数组实现两个堆栈的例子

一个思想是让这两个栈分别从数组的两头开始往中间生长,这样可以尽可能的提高空间利用率。

双堆栈的定义

typedef int Position;
typedef struct SNode* PtrToSNode;
struct SNode{
	ElementType* Data;
	Position Top1;
	Position Top2;
	int MaxSize;
};
typedef PtrToSNode Stack;

双堆栈的创建

Stack CreateDoubleStack(int MaxSize)
{
	Stack S=(Stack)malloc(sizeof(struct SNode));
	S->Data=(ElementType*)malloc(MaxSize*sizeof(ElementType));
	S->Top1=-1;
	S->Top2=MaxSize-1;
	S->MaxSize=MaxSize;
	return S;
}

双堆栈的主要操作

//入栈
//C语言在C99之后新引入了bool这个关键字,只要在开头添加stdbool.h这个头文件就可以和C++一样使用bool了
bool Push(Stack S,ElementType X, int Tag)
{
	if(S->Top1+1==S->Top2){
		printf("堆栈满了\n");
		return false;
	}
	else {
		if(Tag==1)
			S->Data[++(S->Top1)]=X;
		else 
			S->Data[--(S->Top2)]=X;
			return true;
	}
}


//出栈

ElementType Pop(Stack S,int Tag)
{
	if(Tag==1){
		if(S->Top1==-1){
			printf("堆栈1已经空了\n");
			return ERROR;
		}
		else 
			return(S->Data[(S->Top1)--]);
	}
	else{
		if(S->Top2==MaxSize){
			printf("堆栈2已经空了\n");
			return ERROR;
		}
		else 
			return(S->Data[(S->Top2)++]);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值