堆栈(stack)
1.堆栈的定义
可以认为具有一定约束的线性表,其插入和删除都作用于栈顶(Top)的端点位置。且最后入栈的数据最先弹出。
压入栈(Push):插入数据
弹出栈(Pop):取出(删除)数据
2.抽象数据类型
类型名称:堆栈(Stack)
数据对象集:一个有0个或多个元素的有穷线性表
操作集:对于一个具体的长度为正整数的MaxSize的堆栈S∈Stack,记堆栈中的任一元素X∈ElementType,有:
(1)Stack CreatStack(int MaxSize):生成空堆栈,其最大长度为MaxSize;
(2)bool IsFull(Stack S):判断堆栈S是否已满。若S中元素个数等于MaxSize时返回true;否则返回false;
(3)bool Push(Stack S,ElementType X):将元素压入堆栈。若堆栈已满,返回false;否则将数据元素X插入到堆栈S栈顶并返回true;
(4)bool IsEmpty(Stack S):判断堆栈S是否为空。若是返回true;否则返回false;
(5)ElementType Pop(Stack S):删除并返回栈顶元素。若堆栈为空,返回错误信息;否则将栈顶元素从堆栈中删除并返回。
3. C语言实现堆栈
3.1 顺序存储
#include<stdio.h>
#include<stdlib.h>
#define ERROR -1
typedef int Position;
typedef struct Node * PtrToNode;
struct Node{
int * Data;//ElementType 存储元素的数组
Position Top;//栈顶指针
int MaxSize;//堆栈最大容量
};
typedef PtrToNode Stack;
Stack CreatStack(int MaxSize);
bool IsFull(Stack S);
bool Push(Stack S,int X);//bool Push(Stack S,ElementType X);
bool IsEmpty(Stack S);
int Pop(Stack S);//ElementType Pop(Stack S);
void p(Stack S);//打印栈中的数据
int main(){
Stack S=CreatStack(4);//创建一个长度为10的栈
Push(S,1); p(S);
Push(S,2); p(S);
Push(S,3); p(S);
Pop(S); p(S);
Push(S,4); p(S);
Pop(S); p(S);
Pop(S); p(S);
Push(S,5); p(S);
Push(S,6); p(S);
Push(S,7); p(S);
Push(S,8); p(S);
Pop(S); p(S);
Pop(S); p(S);
Pop(S); p(S);
Pop(S); p(S);
Pop(S); p(S);
}
Stack CreatStack(int MaxSize){
Stack S=(Stack)malloc(sizeof(struct Node));
S->Data=(int*)malloc(MaxSize*sizeof(int));
S->Top=-1;
S->MaxSize=MaxSize;
return S;
}
bool IsFull(Stack S){
return(S->Top==S->MaxSize-1);
}
bool Push(Stack S,int X){
if(IsFull(S)){
printf("堆栈已满,插入失败\n");
return false;
}
else{
S->Data[++(S->Top)]=X;
return true;
}
}
bool IsEmpty(Stack S){
return(S->Top==-1);
}
int Pop(Stack S){
if(IsEmpty(S)){
printf("堆栈空,出栈失败\n");
return ERROR;//ERROR 这个值一般根据具体问题做定义,必须是正常的栈元素不可能取到的值
}
else{
return(S->Data[(S->Top)--]);
}
}
void p(Stack S){
int i;
printf("栈内数据:");
if(S->Top==-1){
printf("无 ");
}
for(i=0;i<=S->Top;i++){
printf(" %d ",S->Data[i]);
}
printf("打印完成\n");
}
3.2 链式存储
#include<stdio.h>
#include<stdlib.h>
typedef struct Node * PtrToNode;//将Node *重新命名为 PtrToNode
struct Node{
int Data;//结点数据
PtrToNode Next;//指向下一结点的指针
};
typedef PtrToNode Stack;
Stack CreatStack();//构建堆栈的头结点,返回该结点指针
bool IsEmpty(Stack S);
bool Push(Stack S,int X);//bool Push(Stack S,ElementType X);
int Pop(Stack S);//ElementType Pop(Stack S);
void p(Stack S);
int main(){
Stack s=CreatStack();
Pop(s); p(s);
Push(s,1);p(s);
Push(s,2);p(s);
Push(s,3);p(s);
Pop(s); p(s);
Pop(s); p(s);
Pop(s); p(s);
}
Stack CreatStack(){
Stack S;
S=(Stack)malloc(sizeof(struct Node));//头结点的类型可不定义
S->Next=NULL;
return S;
}
bool IsEmpty(Stack S){
return (S->Next==NULL);
}
bool Push(Stack S,int X){
PtrToNode TmpCell;
TmpCell=(PtrToNode)malloc(sizeof(struct Node));
TmpCell->Data=X;
TmpCell->Next=S->Next;
S->Next=TmpCell;//一直在头结点后插入
return true;
}
int Pop(Stack S){
PtrToNode FirstCell;
//取一结构体指针复制头结点后的第一个元素
//即栈顶元素
int TopElem;//栈顶元素的值
if(IsEmpty(S)){
printf("堆栈空\n");
}
else{
FirstCell=S->Next;
TopElem=S->Data;
S->Next=FirstCell->Next;//让头结点指向第二个元素
free(FirstCell);
return TopElem;
}
}
void p(Stack S){
int i;
printf("栈内数据:");
if(S->Next==NULL){
printf("无 ");
}
else{
while(S->Next){
S=S->Next;
printf(" %d ",S->Data);
}
}
printf("打印完成\n");
}