栈
------------------------------------------------------------------------------------------------
1、定义 : 限定只能在表的一端进行插入和删除运算的线性表(只能在栈顶操作)表尾端。
2、逻辑结构: 与线性表相同,仍为一对一关系
3、存储结构: 只能在栈顶运算,且访问结点时依照后进先出(LIFO)或先进后出(FILO)的原则
4、运算规则: 只能在栈顶运算
5、实现方法: 关键是编写入栈和出栈函数,具体实现依顺序栈或链栈的不同而不同
基本操作有入栈、出栈、读栈顶元素值、建栈、或判断栈满、栈空等。
6、栈的物理结构
注意:在每次入栈的时候, top 指针会在存储的位置的上一个位置:
7、栈的抽象数据类型定义:
ADT{
数据对象:D={ ai | ai 属于 ElemSet,i=1,2 ,.... , n, n>=0 }
数据关系:R1={ < ai-1 , ai > | ai-1 , ai 属于 D , i=2, ... , n}
约定 an 端为栈顶, a1 端为栈底。
基本操作:
InitStack(&S)
操作结果:构造一个空栈S。
DestroyStack(&S)
初始条件:栈S已存在。
操作结果:栈S被销毁。
ClaerStack(&S)
初始条件:栈S已存在。
操作结果:将栈S清空为空栈
StackEmpty(&S)
初始条件:栈S已存在。
操作结果:若栈为空栈,则返回TRUE,否则FLASE。
StackLength(&S)
初始条件:栈S已存在。
操作结果:返回S的元素个数,即栈的长度
GetTop(S,&e)
初始条件:栈S已存在且非为空。
操作结果:用e返回S的栈顶元素
Push(&S,e)
初始条件:栈S已存在。
操作结果:插入元素 e 为新的栈顶元素
Pop(&S)
初始条件:栈S已存在且非为空。
操作结果:删除S的栈顶元素,并用e返回其值
StackTraverse( S, visit() )
初始条件:栈S已存在且非为空。
操作结果:从栈底到栈顶依次对S的每个元素调用 Visit() 。一旦Visit()失败,则操作失 败。
}ADT Stack
8、栈的条件:
栈不存在的条件 : base =NULL;
栈为空的条件: base=top;
栈满的条件: top- base=stacksize;
栈满的条件: top- base=stacksize;
9、栈的实现:(和线性表类似,栈也有两种存储方式)
顺序栈的操作系统:
完整代码:
注:需要以 .cpp 为后缀名
//头文件
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>
//宏定义
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int SElemType;
typedef int Status;
//栈的顺序结构体
typedef struct{
SElemType *base; //在栈构造之前和销毁之后,base 的值为NULL;
SElemType *top; //栈顶指针
int stacksize; //当前已分配的存储空间,以元素为单位
}SqStack;
//------------基本操作的函数原型说明--------------
//Status InitStack(SqStack &S); //构造一个空栈S
//Status DestroyStack(SqStack &S); //销毁栈S,S不再存在
//Status ClearStack(SqStack &s); //把栈S置位空
//Status StackEmpty(SqStack S); //若栈S为空栈,则返回TRUE,否则返回FALSE
//int StackLength(SqStack S); //返回S的元素个数,即栈的长度
//Status GetTop(SqStack S,SElemType &e); //若栈不为空,则用e返回S的栈顶元素,并返回OK,否则返回ERROR
//Status Push(SqStack &S,SElemType e); //插入元素e为新的栈顶元素
//Status Pop(SqStack &S,SElemType &e); //若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR
//Status StackTraverse(SqStack S,Status (*visit) () );
//从栈底到栈顶依次对栈中每个元素调用函数 visit() , 一旦 visit() 失败,则操作失败
//1.构建栈
Status InitStack(SqStack &S){
//构造一个空栈S
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(! S.base) exit(OVERFLOW); //存储分配失败
S.top=S.base; //当栈为空时,栈底等于栈顶
S.stacksize=STACK_INIT_SIZE; //栈可存储的个数
return OK;
}
//2.销毁栈
Status DestroyStack(SqStack &S){
S.top=NULL;
S.stacksize=0;
free(S.base);
return OK;
}
//3.清空栈
Status ClearStack(SqStack &S){
S.top=S.base; //栈顶和栈底指向同一个位置,即为空
return OK;
}
//4.判断栈是否为空
Status StackEmpty( SqStack S)
{
if(S.top==S.base)
return ERROR;
else
return TRUE;
}
//5.求栈的长度
Status StackLength(SqStack S)
{
int n;
if(S.top==S.base)
return FALSE;
else{
n=S.top-S.base;
return n;
}
}
//6.求栈顶元素
Status GetTop(SqStack S,SElemType &e)
{
if(S.top==S.base)
return FALSE;
else
return ( e=*(S.top-1) );
}
//7.栈顶插入元素
Status Push(SqStack &S,SElemType &e)
{ //插入元素 e 为新的栈顶元素
if(S.top-S.base >= STACK_INIT_SIZE) //栈满的时候就需要追加存储空间
{
S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base) exit(OVERFLOW); //存储空间分配失败
S.top=S.base+S.stacksize; //栈底的位置可能改变,需要重新定位栈顶元素
//S.top 还是之前的那个没有存储的位置
S.stacksize = S.stacksize+STACKINCREMENT;
}
*S.top=e;
S.top++;
return OK;
}
//8.栈顶出栈元素
Status Pop(SqStack &S,SElemType &e){
//若栈不为空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK ,否则返回ERROR
if(S.top == S.base) return ERROR;
e=*(--S.top); //可以不加括号,但需要记住的是,需要让 top 指针减 1 ,再取出元素
return OK;
}
//9.遍历栈
Status StackTraverse(SqStack S){
if(S.base==NULL) return ERROR;
if(S.top==S.base){
printf("栈为空,没有元素-------!");
return FALSE;
}
SElemType *p=S.top; //先找出 top 的地址
while(p > S.base)
{
p--;
printf("%d\n",*p);
}
return OK;
}
/*
Status StackTraverse(SqStack S,Status (*visit) () )
{
whlie(S.top != S.base)
visit(--S.top); //先把指针减 1 ,再输出其元素
}
*/
//主函数
void main(){
SqStack S;
int whilenum=1;
int stack_length;
int word;
char anykey;
int IS_Result;
do{
printf("------------------------------Use Stack----------------------------\n");
printf("1.Buliding an empty Stack. \n");
printf("2.Destruction of the Stack. \n");
printf("3.Clear the Stack. \n");
printf("4.Determines whether the Stack is empty. \n");
printf("5.Caculate the Stack length. \n");
printf("6.Obtain the top element Stack. \n");
printf("7.Insert elements into the top of the Stack. \n");
printf("8.The output Stack top element. \n");
printf("9.Ergodic output stack. \n");
printf("10.The end of the Stack. \n");
printf("11.\n");
printf("12.\n");
printf("13.\n");
printf("--------------------------------------------------------------------\n");
whilenum=1;
int choice;
printf("Please enter your choice.\n");
scanf("%d",&choice);
switch(choice){
//初始化栈
case 1:
printf("Buliding an empty Stack.\n");
IS_Result=InitStack(S);
if(IS_Result=1)
printf("Construct an empty Stack.\n");
else
printf("Rrror\n");
printf("\n\n");
printf("anykey to continue!");
scanf("%c",&anykey);
scanf("%c",&anykey);
break;
//销毁栈
case 2:
printf("Destruction of the Stack.\n");
if(DestroyStack(S)==1)
printf("Destruction of the Stack succeed. \n");
else
printf("Destruction of the Stack succeed error. \n");
printf("anykey to continue!");
break;
//清空栈
case 3:
printf("Clear the Stack.\n");
if(ClearStack(S)==1)
printf("Clear the Stack succeed.\n");
else
printf("Clear the Stack error.\n");
printf("anykey to continue!");
break;
//判断栈是否为空
case 4:
printf("The Stack is empty? \n");
if( StackEmpty(S) == 1)
printf("NO!\n");
else
printf("YES!\n");
printf("anykey to continue!");
scanf("%c",&anykey);
scanf("%c",&anykey);
break;
//Calculate the stack length.
case 5:
printf("Calculate the stack length,the length of Atack is:");
stack_length=StackLength(S);
printf("%d",stack_length);
printf("anykey to continue!");
scanf("%c",&anykey);
scanf("%c",&anykey);
break;
//获得栈顶元素
case 6:
printf("Get the top element of the stack.\n");
GetTop(S,word);
printf("the word is : %d",word);
printf("anykey to continue!");
scanf("%c",&anykey);
scanf("%c",&anykey);
break;
//入栈
case 7:
printf("Please enter the char you want to enter.");
scanf("%d",&word);
Push(S,word);
printf("anykey to continue!");
scanf("%c",&anykey);
scanf("%c",&anykey);
break;
//出栈
case 8:
printf("The output Stack top element.\n");
Pop(S,word);
printf("the word is : %d",word);
printf("anykey to continue!");
scanf("%c",&anykey);
scanf("%c",&anykey);
break;
//遍历栈
case 9:
printf("Traverse the Stack:");
StackTraverse(S);
printf("anykey to continue!");
scanf("%c",&anykey);
scanf("%c",&anykey);
break;
//结束
case 10:
printf("Succeding end. \n");
whilenum=0;
break;
}
system("cls");
}while(whilenum);
}
如有错误,敬请指出!