数据结构C语言——堆栈

在C语言数据结构中,关于数据元素的类型定义均用“ ElemType e;”来表示,其中e是表示数据元素的变量,而ElemType则是它的类型,ElemType的含义就是“数据元素的类型”,是一个抽象的概念,是表示我们所要使用的数据元素应有的类型。

ElemType是数据结构上为了说明问题而用的一个词。它是element type(“元素的类型”)的简化体。

因为数据结构是讨论抽象的数据结构和算法,一种结构中元素的类型不一定是整型、字符型、浮点型或者用户自定义类型,为了不重复说明,使用过程用 “elemtype” 代表所有可能的数据类型,简单明了的概括整体。

在算法中,除特别说明外,规定ElemType的默认是int型。

顺序栈定义

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

创建空堆栈
Stack CreateStack(int 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;
}

入栈,bool Push(Stack S,ElementType X);
将元素压入堆栈,先判断堆栈是否满

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

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

出栈ElementType Pop(Stack S);删除并返回栈顶元素,若堆栈为空则返回false,否则返回true
先判断栈是否空,若不空返回该值,同时top-1,否则要返回一个ElementType类型的特殊错误标志,取ERROR,这个值一般是正常栈元素取不到的值

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

ElementType Pop(Stack S){
	if(IsEmpty(S)){
		printf("栈空!\n");
		return ERROR;
	}
	else{
		return (S->Data[(S->Top)--])
	}
}

数组实现两个堆栈的例子
用一个数组实现两个堆栈,要求最大可能利用数组空间,使数组只要有空间入栈操作就成功,写出入栈出栈操作函数
方法一:将数组一分为二分配给两个堆栈使用,一个堆栈的底部在数组的起始位置,另一个的底部在数组的中间位置,两个Top指针都沿着同一个方向增长,缺点涉及多个数据的移位。(假如前面的栈遇到了第二个栈的头时,需要第二个栈整体向后移)
方法二:这两个栈分别从 数组的两头开始向中间生长,当两个栈的栈顶指针相遇时表示两个栈都满了。

双堆栈的定义

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

创建空堆栈
Stack CreateStack(int MaxSize);

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

入栈

bool Push(Stack S,ElementType X,int tag){
	if(S->Top2-S->Top1==1){
		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("栈空\n");
			return ERROR;
		}
		else
			return S->Data[(S->Top1)--)];
	}
	else{
		if(S->Top1==MaxSize){
			printf("栈空\n");
			return ERROR;
		}
		else
			return S->Data[(S->Top2)++)];
		}
}

栈的链式存储实现
栈的链式存储与单链表类似,单操作受限于插入和删除只能在栈链的栈顶进行,栈顶指针Top就是链表的头指针.

栈链的定义

typedef struct SNode * PtrToSNode;
struct SNode{
	ElementType Data;
	PtrToSNode Next;
};
typedef PtrToSNode Stack;
Stack CreatStack(){
	Stack S=(Stack)malloc(sizeof(struct SNode));
	S->Next=NULL;
	return S;
}

bool IsEmpty(Stack S){
	return (S->Next==NULL);
}

bool Push(Stack S,ElementType X){
	PtrToSNode TmpCell;
	TmpCell=(PtrToSNode)malloc(sizeof(struct SNode));
	TmpCell->Data=X;
	TmpCell->Next=S->Next;
	S->Next=TmpCell;
	return true;
}

ElementType Pop(Stack S){
	//删除元素并返回堆栈S的栈顶元素
	PtrToSNode FirstCell;
	ElementType TopElem;
	if(IsEmpty(S)){
		printf("栈空");
		return ERROR;
	}
	else{
		FirstCell=S->Next;
		TopElem=FirstCell->Data;
		S->Next=FirstCell->Next;
		free(FirstCell);
		return TopElem;
	}
}

堆栈的应用:表达式求值
后缀表达式:从左到右读入后缀表达式的各项,并根据读入的对象进行操作
1.当读入的是一个运算数时,把他压入栈中
2.当读入的是一个运算符时,就从堆栈中弹出适当的运算数进行计算,再把结果压入栈中
3.处理完全部后,栈中栈顶的元素就是表达式的值

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MAXOP 100
#define INFINITY 1e9
typedef double ElementType;
typedef enum{num,opr,end} Type;
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;
}

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

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

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

ElementType Pop(Stack S){
	if(IsEmpty(S)){
		printf("栈空!\n");
		return ERROR;
	}
	else{
		return (S->Data[(S->Top)--])
	}
}

Type GetOp(char * Expr,int *start,char *str){
	int i=0;
	while((str[0)=Expr[(*start)++]==' ');
	while(str[i]!=' '&&str[i]!='\n')
		str[++i]Expr[(*start)++];
	if(str[i]=='\0')
		(*start)--;
	str[i]='\0';
	if(i==0)
		return end;
	else if(isdigit(str[0])
		return num;
	else
		return opr;
}
ElementType PostfixExp(char * Expr){
	Stack S;
	Type T;
	ElementType Op1,Op2;
	char str[MAXOP];
	int start=0;
	S=CreateStack(MAXOP);
	Op1=Op2=0;
	while((T=GetOp(Expr,&start,str))!=end){
		if(T==num)
			Push(S,auto(str);
		else{
			if(!IsEmpty(S))
				Op2=Pop(S);
			else
				Op2=INFINITY;
			if(!IsEmpty(S))
				Op1=Pop(S);
			else
				Op2=INFINITY;
			switch(str[0]){
				case '+':Push(S,Op1+Op2);
					break;
				case '-':Push(S,Op1-Op2);
					break;
				case '*':Push(S,Op1*Op2);
					break;
				case '/':
					if(Op2!=0.0)
						Push(S,Op1+Op2);
					else{
						printf("除法非法\n");
						Op2=INFINITY;
					}
					break;
				default:
					printf("错误!\n");
					Op2=INFINITY;
					break;
			}
			if(Op2>=INFINITY)
				break;
		}
	}
	if(Op2<INFINITY)
		if(!IsEmpty(S))
			Op2=Pop(S);
		else
			Op2=INFINITY;
		free(S);
		return Op2;
}
int main(){
	char Expr[MAXOP];
	ElementType f;
	gets(Expr);
	f=PostfixExp(Expr);
	if(f<INFINITY)
		printf("%.4f\n",f);
	else
		printf("表达式错误\n");
	return 0;
}
  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值