顺序栈与链式栈的实现
程序员文章站
2022-03-12 17:28:58
...
栈的概念:
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
顺序栈:
base.h
这个头文件主要用来存放公用的常量和类型。
//base.h
//-----公用的常量和类型----------
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
#include<malloc.h>
#include<string.h>
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1 //不可行的 infeaslble
#define OVERFLOW -2
typedef int Status;
typedef int SElemType;
sq_Stack.h
sq_Stack.h头文件用来具体实体实现栈的基本操作。
//sq_stack.h 顺序栈
//-------------栈的顺序存储表示----------------
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
typedef struct{
SElemType *base; //在栈构造之前和销毁之后,base的值为NULL
SElemType *top; //栈顶指针
int stacksize; //当前分配的存储空间,以元素为单位
}SqStack;
//----基本操作的函数原型说明-----------
//构建一个空栈S
Status InitStack_Sq(SqStack &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;
}//InitStack_Sq
//销毁栈S
Status DestroyStack_Sq(SqStack &S){
if(S.base){
free(S.base);
S.top = S.base = NULL;
S.stacksize = 0;
cout<<"栈销毁成功!"<<endl;
return OK;
}else{
cout<<"栈不存在,不需要销毁!"<<endl;
return ERROR;
}
}//DestroyStack_Sq
//初始条件:栈S存在
//操作结果:清空栈
Status CleanStack_Sq(SqStack &S){
S.top = S.base;
return OK;
}//CleanStack_Sq
//初始条件:栈S存在
//操作结果:若为空栈,返回TRUE,否则FALSE
Status StackEmpty_Sq(SqStack S){
if(S.top == S.base){
cout<<"栈为空!"<<endl;
return TRUE;
}
else{
cout<<"栈不为空!"<<endl;
return FALSE;
}
}//StackEmpty_Sq
//初始条件:栈S存在
//操作结果:返回栈内元素个数,即栈的长度
int StackLength_Sq(SqStack S){
int len;
len = (S.top - S.base);
return len;
}//StackLength_Sq
//初始条件:栈S存在
//操作结果:用e返回S的栈顶元素
Status GetTop_Sq(SqStack S, SElemType &e){
if(S.top == S.base)//判空
return ERROR;
else{
e = *(S.top - 1);
return OK;
}
}//GetTop_Sq
//初始条件:栈S存在
//操作结果:插入元素e为新的栈顶元素
Status Push_Sq(SqStack &S, SElemType e){
//判满,追加存储空间
if(S.top - S.base >= S.stacksize){
S.base = (SElemType *)realloc(S.base,
(S.stacksize + STACKINCREMENT) * sizeof(SElemType));
if(!S.base)//存储分配失败
exit(OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e; //插入元素
return OK;
}//Push_Sq
//初始条件:栈S存在
//操作结果:删除S的栈顶元素,并用e返回其值
Status Pop_Sq(SqStack &S, SElemType &e){
if(S.top == S.base) //判空
return ERROR;
e = *--S.top; //返回删除元素的值
return OK;
}//Pop_Sq
//初始条件:栈S存在
//操作结果:遍历栈元素并显示
Status StackTraverse_Sq(SqStack S){
if(S.base){ //判断栈是否存在
if(S.top == S.base) //判空
cout<<"此栈是个空栈!"<<endl;
else{
SElemType *p;
p = S.top;
while(p > S.base)
{
p--;
cout<<*p<<" ";
}
cout<<endl;
}
return OK;
}else{
cout<<"栈不存在!"<<endl;
return ERROR;
}
}//StackTraverse_Sq
sqStackText.cpp
用来测试顺序栈的基本操作函数。
#include "base.h"
#include "sq_stack.h"
//用来测试顺序栈的基本操作
int main(){
SqStack S;
SElemType e;
InitStack_Sq(S);
StackTraverse_Sq(S);
//给空栈赋值
for(e = 0; e<10; e++){
Push_Sq(S, e);
}
cout<<"栈的遍历:";
StackTraverse_Sq(S);
Push_Sq(S, 15);
cout<<"压栈15后栈的遍历:";
StackTraverse_Sq(S);
Pop_Sq(S, e);
cout<<"出栈后栈的遍历:";
StackTraverse_Sq(S);
cout<<"被删除的元素是:"<<e<<endl;
GetTop_Sq(S, e);
cout<<"获取栈顶元素:"<<e<<endl;
cout<<"栈的长度为(即栈内元素个数):"
<<StackLength_Sq(S)<<endl;
cout<<"判栈空:";
StackEmpty_Sq(S);
cout<<"清空栈!"<<endl;
CleanStack_Sq(S);
cout<<"判栈空:";
StackEmpty_Sq(S);
cout<<"销毁栈:";
DestroyStack_Sq(S);
cout<<"再次销毁栈:";
DestroyStack_Sq(S);
return OK;
}
程序运行结果:
链式栈:
link_stack.h
链式表的具体代码实现:
//link_stack.h 链式栈
//-------------栈的链式存储表示----------------
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
typedef struct StackNode{
SElemType date; //数据域
struct StackNode *next;
}StackNode, *LinkStackPtr;
typedef struct LinkStack{
LinkStackPtr top; //栈顶
int count; //记录栈元素个数
}*PLinkStack;
//----基本操作的函数原型说明-----------
//构建一个空栈S
Status InitStack_L(PLinkStack* S){
//分配一个节点的初始化空间
*S = (PLinkStack)malloc(sizeof(struct LinkStack));
(*S)->top = NULL; //栈顶指针指向空
(*S)->count = 0; //栈中元素个数初始为0
return OK;
}//InitStack_L
//初始条件:栈S存在
//操作结果:清空栈
Status CleanStack_L(PLinkStack &S){
LinkStackPtr p;
//栈不为空时,进行循环,释放每一个节点的空间
while(S->top){
p = S->top;
S->top = S->top->next;
S->count--;
free(p);
}
return OK;
}//CleanStack_L
//销毁栈S
Status DestroyStack_L(PLinkStack* S){
CleanStack_L(*S); //先清空栈
free(*S); //释放栈所有空间
cout<<"栈销毁成功!"<<endl;
return OK;
}//DestroyStack_L
//初始条件:栈S存在
//操作结果:若为空栈,返回TRUE,否则FALSE
Status StackEmpty_L(PLinkStack S){
if(S->top){ //栈顶存在
cout<<"栈不为空!"<<endl;
return TRUE;
}else{
cout<<"栈为空!"<<endl;
return FALSE;
}
}//StackEmpty_L
//初始条件:栈S存在
//操作结果:返回栈内元素个数,即栈的长度
int StackLength_L(PLinkStack S){
return S->count;
}//StackLength_L
//初始条件:栈S存在
//操作结果:用e返回S的栈顶元素
Status GetTop_L(PLinkStack S, SElemType &e){
if(!S->top)
return ERROR;
e = S->top->date;
return OK;
}//GetTop_L
//初始条件:栈S存在
//操作结果:插入元素e为新的栈顶元素
Status Push_L(PLinkStack &S, SElemType e){
LinkStackPtr p = (LinkStackPtr)malloc(sizeof(struct StackNode));
p->date = e;
p->next = S->top;
S->top = p;
S->count++;
return OK;
}//Push_L
//初始条件:栈S存在
//操作结果:删除S的栈顶元素,并用e返回其值
Status Pop_L(PLinkStack &S, SElemType &e){
LinkStackPtr p;
if(!S->top){
return ERROR;
}
e = S->top->date;
p = S->top;
S->top = S->top->next;
S->count--;
free(p);
return OK;
}//Pop_L
//初始条件:栈S存在
//操作结果:遍历栈元素并显示
Status StackTraverse_L(PLinkStack S){
if(S->top){
LinkStackPtr p;
p = S->top;
while(p){
cout<<p->date<<" ";
p = p->next;
}
cout<<endl;
return OK;
}else{
cout<<"此栈为空栈!"<<endl;
return OK;
}
}//StackTraverse_L
linkStackText
链式栈的测试:
void linkStackText(){
PLinkStack S;
SElemType e;
InitStack_L(&S);
StackTraverse_L(S);
//给空栈赋值
for(e = 0; e<10; e++){
Push_L(S, e);
}
cout<<"栈的遍历:";
StackTraverse_L(S);
Push_L(S, 15);
cout<<"压栈15后栈的遍历:";
StackTraverse_L(S);
Pop_L(S, e);
cout<<"出栈后栈的遍历:";
StackTraverse_L(S);
cout<<"被删除的元素是:"<<e<<endl;
GetTop_L(S, e);
cout<<"获取栈顶元素:"<<e<<endl;
cout<<"栈的长度为(即栈内元素个数):"
<<StackLength_L(S)<<endl;
cout<<"判栈空:";
StackEmpty_L(S);
cout<<"清空栈!"<<endl;
CleanStack_L(S);
cout<<"栈的遍历:";
StackTraverse_L(S);
cout<<"判栈空:";
StackEmpty_L(S);
cout<<"销毁栈:";
DestroyStack_L(&S);
}
链式栈测试运行结果:
上一篇: css怎样实现图片的渐渐隐藏效果
下一篇: 数据结构-栈的顺序存储和链式存储