在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;
}