一、顺序栈
//
// Created by ASUS on 2021/8/26.
//
#include <iostream>
typedef int ElemType;
#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
ElemType data[MaxSize]; //静态数组中存放栈中元素
int top; //栈顶指针
}SqStack;
//初始化栈
bool InitStack(SqStack &S) {
S.top = -1; //初始化栈顶指针 | S.top = 0;
}
//栈顶判空
bool StackEmpty(SqStack S){
if(S.top == -1) //栈空 | S.top = 0;
return true;
else //不空
return false;
}
//新元素入栈
bool Push(SqStack &S, ElemType x){
if(S.top == MaxSize-1) //栈满,报错 | S.top == MaxSize
return false;
S.top = S.top + 1; //指针先加1
S.data[S.top] = x; //新元素入栈 这两句等价于S.data[++S.top] = x; | S.data[S.top++] = x
return true;
}
//出栈操作
bool Pool(SqStack &S, ElemType &x){
if(S.top == -1) //栈空,报错 | S.top == 0
return false;
x = S.data[S.top]; //栈顶元素先出栈
S.top = S.top - 1; //指针再减1 这两句等价于x = S.data[S.top--]; | x = S.data[--S.top];
return true;
}
//获取栈顶元素
bool GetTop(SqStack S, ElemType &x){
if(S.top == -1) //栈空,报错 | S.top == 0
return false;
x = S.data[S.top]; //栈顶元素先出栈
//S.top = S.top - 1; //指针再减1 这一步不要!!!
return true;
}
int main() {
//声明一个顺序栈
SqStack S;
//初始化一个空栈
printf("初始化栈是否成功:%s\n", InitStack(S) ? "是" : "否");
//判空
printf("栈是否为空:%s\n", StackEmpty(S) ? "是" : "否");
//push(赋值)
printf("开始赋值\n");
for(int i = 0; i < 5; i++){
if(Push(S, i))
continue;
else
break;
}
//判空
printf("栈是否为空:%s\n", StackEmpty(S) ? "是" : "否");
//获取栈顶元素
int x;
GetTop(S, x);
printf("栈顶元素为:%d\n", x);
//出栈
printf("开始出栈:");
for(int i = 0; i < 5; i++){
Pool(S, x);
printf("%d ", x);
}
printf("\n");
//判空
printf("栈是否为空:%s\n", StackEmpty(S) ? "是" : "否");
return 0;
}
二、共享栈
//
// @Author: Brisa
// @Date: 2021/8/27
// @Description: 共享栈操作
//
#include<stdio.h>
#define MaxSize 10 //定义共享栈中元素的最大个数
#define ElemType int
//共享栈的类型定义
typedef struct{
ElemType data[MaxSize]; //静态数组存放栈中元素
int top1; //1号栈顶指针
int top2; //2号栈顶指针
} ShStack;
/*函数声明*/
void InitShStack(ShStack& S); //1.初始化共享栈
bool Stack1Empty(ShStack S); //2. 1号栈判空
bool Stack2Empty(ShStack S); //2. 2号栈判空
bool Push1(ShStack& S, ElemType x); //3. 1号栈入栈
bool Push2(ShStack& S, ElemType x); //4. 2号栈入栈
bool Pop1(ShStack& S, ElemType& x); //5. 1号栈出栈
bool Pop2(ShStack& S, ElemType& x); //6. 2号栈出栈
bool GetTop1(ShStack S, ElemType& x); //7. 1号栈读取栈顶元素
bool GetTop2(ShStack S, ElemType& x); //8. 2号栈读取栈顶元素
//1.初始化共享栈
void InitShStack(ShStack &S){
S.top1 = -1; //1号栈顶指针初始化为-1
S.top2 = MaxSize; //1号栈顶指针初始化为MaxSize
}
//2.1号栈判空
bool Stack1Empty(ShStack S){
return (S.top1 == -1);
}
//3.2号栈判空
bool Stack2Empty(ShStack S){
return (S.top2 == MaxSize);
}
//4.1号栈入栈
bool Push1(ShStack &S, ElemType e){
if(S.top1 + 1 == S.top2) //栈满
return false;
S.data[++S.top1] = e;
return true;
}
//5.2号栈入栈
bool Push2(ShStack &S, ElemType e){
if(S.top1 + 1 == S.top2) //栈满
return false;
S.data[--S.top2] = e;
return true;
}
//6.1号出栈操作
bool Pop1(ShStack &S, ElemType &e){
if(S.top1 == -1) //1号栈空
return false;
e = S.data[S.top1--];
return true;
}
//7.2号出栈操作
bool Pop2(ShStack &S, ElemType &e){
if(S.top2 == MaxSize) //2号栈空
return false;
e = S.data[S.top2++];
return true;
}
//8.1号读取栈顶元素
bool GetTop1(ShStack S, ElemType &e){
if(S.top1 == -1) //1号栈空
return false;
e = S.data[S.top1];
return true;
}
//9.2号读取栈顶元素
bool GetTop2(ShStack S, ElemType &e){
if(S.top2 == MaxSize) //2号栈空
return false;
e = S.data[S.top2];
return true;
}
int main(){
//声明一个共享栈
ShStack S;
//初始化共享栈
InitShStack(S);
/*1号栈基本操作*/
//1号栈-判空
printf("当前1号栈是否为空:%s \n", Stack1Empty(S)?"是":"否");
//1号栈-入栈
ElemType e11;
printf("请输入1号栈入栈元素的值:");
scanf("%d",&e11);
if(Push1(S, e11))
printf("1号栈新元素入栈成功!\n");
else
printf("共享栈已满,1号栈新元素入栈失败!\n");
//1号栈-读取栈顶元素
ElemType e12;
if(GetTop1(S, e12))
printf("获取1号栈栈顶元素成功!栈顶元素为:%d\n", e12);
else
printf("1号栈已空,读取栈顶元素失败!\n");
//1号栈-出栈
ElemType e13;
if(Pop1(S, e13))
printf("1号栈栈顶元素出栈成功!栈顶元素为:%d\n", e13);
else
printf("1号栈已空,栈顶元素出栈失败!\n");
//1号栈-再次读取栈顶元素
ElemType e14;
if(GetTop1(S, e14))
printf("获取1号栈栈顶元素成功!栈顶元素为:%d\n", e14);
else
printf("1号栈已空,读取栈顶元素失败!\n");
/*2号栈基本操作*/
//2号栈-判空
printf("当前2号栈是否为空:%s \n", Stack2Empty(S)?"是":"否");
//2号栈-入栈
ElemType e21;
printf("请输入2号栈入栈元素的值:");
scanf("%d",&e21);
if(Push2(S, e21))
printf("2号栈新元素入栈成功!\n");
else
printf("共享栈已满,2号栈新元素入栈失败!\n");
//1号栈-读取栈顶元素
ElemType e22;
if(GetTop1(S, e12))
printf("获取2号栈栈顶元素成功!栈顶元素为:%d\n", e22);
else
printf("2号栈已空,读取栈顶元素失败!\n");
//2号栈-出栈
ElemType e23;
if(Pop2(S, e23))
printf("2号栈栈顶元素出栈成功!栈顶元素为:%d\n", e23);
else
printf("2号栈已空,栈顶元素出栈失败!\n");
//2号栈-再次读取栈顶元素
ElemType e24;
if(GetTop2(S, e24))
printf("获取2号栈栈顶元素成功!栈顶元素为:%d\n", e24);
else
printf("2号栈已空,读取栈顶元素失败!\n");
return 0;
}
三、链栈
1.不带头结点
//
// @Author: Brisa
// @Date: 2021/8/27
// @Description: 链栈(不带头结点)操作
//
#include<stdio.h>
#include<stdlib.h>
#define ElemType int
//链栈类型定义
typedef struct LinkStackNode{
ElemType data; //数据域
struct LinkStackNode *next; //指针域
}SNode, *LiStack;
//函数声明
/*函数声明*/
bool InitLinkStack(LiStack& S); //1.初始化链栈
bool LiStackEmpty(LiStack S); //2.判空
bool Push(LiStack& S, ElemType e); //3.入栈
bool Pop(LiStack& S, ElemType& e); //4.出栈
bool GetTop(LiStack S, ElemType& e); //5.读取栈顶元素
//1.初始化链栈(不带头结点)
bool InitLinkStack(LiStack &S){
S = NULL; //初始化为空,暂时没有任何节点
return true;
}
//2.判空
bool LiStackEmpty(LiStack S){
return (S == NULL);
}
//3.入栈
bool Push(LiStack& S, ElemType e){
SNode *p = (SNode *)malloc(sizeof(SNode));
if(p == NULL)
return false;//内存分配失败
p->data = e;
p->next = S;
S= p;
return true;
}
//4.出栈
bool Pop(LiStack& S, ElemType& e){
if(S == NULL)
return false;//栈空
SNode *p;
p = S;
e = p->data;
S = p->next;
free(p);
return true;
}
//5.读取栈顶元素
bool GetTop(LiStack S, ElemType& e){
if(S == NULL)
return false;//栈空
e = S->data;
return true;
}
int main(){
//声明一个链栈
LiStack S;
//初始化栈
InitLinkStack(S);
//判空
printf("当前栈是否为空:%s \n", LiStackEmpty(S)?"是":"否");
//入栈操作
ElemType e1;
printf("请输入待入栈元素的值:");
scanf("%d", &e1);
if(Push(S, e1))
printf("新元素入栈成功!\n");
else
printf("内存分配失败!\n");
//读取栈顶元素
ElemType e2;
if(GetTop(S, e2))
printf("读取栈顶元素成功!栈顶元素为:%d\n",e2);
else
printf("栈空,读取栈顶元素失败!\n");
//出栈
ElemType e3;
if(Pop(S, e3))
printf("出栈成功,出栈的栈顶元素为:%d \n", e3);
else
printf("栈空,出栈失败!\n");
//读取栈顶元素
ElemType e4;
if(GetTop(S, e4))
printf("读取栈顶元素成功!栈顶元素为:%d\n",e4);
else
printf("栈空,读取栈顶元素失败!\n");
return 0;
}
2.带头结点
//
// @Author: Brisa
// @Date: 2021/8/27
// @Description: 链栈(带头结点)操作
//
#include<stdio.h>
#include<stdlib.h>
#define ElemType int
//链栈类型定义
typedef struct LinkStackNode{
ElemType data; //数据域
struct LinkStackNode *next; //指针域
}SNode, *LiStack;
//函数声明
/*函数声明*/
bool InitLinkStack(LiStack& S); //1.初始化链栈
bool LiStackEmpty(LiStack S); //2.判空
bool Push(LiStack& S, ElemType e); //3.入栈
bool Pop(LiStack& S, ElemType& e); //4.出栈
bool GetTop(LiStack S, ElemType& e); //5.读取栈顶元素
//1.初始化链栈(带头结点)
bool InitLinkStack(LiStack &S){
S = (SNode *) malloc(sizeof(SNode));
if(S == NULL)
return false; //内存不足,分配失败
S->next = NULL; //头结点之后,暂时没有任何节点
return true;
}
//2.判空
bool LiStackEmpty(LiStack S){
return (S->next == NULL);
}
//3.入栈
bool Push(LiStack& S, ElemType e){
SNode *p = (SNode *)malloc(sizeof(SNode));
if(p == NULL)
return false;//内存分配失败
p->data = e;
p->next = S->next;
S->next = p;
return true;
}
//4.出栈
bool Pop(LiStack& S, ElemType& e){
if(S->next == NULL)
return false;//栈空
SNode *p;
p = S->next;
e = p->data;
S->next = p->next;
free(p);
return true;
}
//5.读取栈顶元素
bool GetTop(LiStack S, ElemType& e){
if(S == NULL)
return false;//栈空
e = S->next->data;
return true;
}
int main(){
//声明一个链栈
LiStack S;
//初始化栈
InitLinkStack(S);
//判空
printf("当前栈是否为空:%s \n", LiStackEmpty(S)?"是":"否");
//入栈操作
ElemType e1;
printf("请输入待入栈元素的值:");
scanf("%d", &e1);
if(Push(S, e1))
printf("新元素入栈成功!\n");
else
printf("内存分配失败!\n");
//读取栈顶元素
ElemType e2;
if(GetTop(S, e2))
printf("读取栈顶元素成功!栈顶元素为:%d\n",e2);
else
printf("栈空,读取栈顶元素失败!\n");
//出栈
ElemType e3;
if(Pop(S, e3))
printf("出栈成功,出栈的栈顶元素为:%d \n", e3);
else
printf("栈空,出栈失败!\n");
//读取栈顶元素
ElemType e4;
if(GetTop(S, e4))
printf("读取栈顶元素成功!栈顶元素为:%d\n",e4);
else
printf("栈空,读取栈顶元素失败!\n");
return 0;
}
四、栈的应用
括号匹配测试,递归(阶乘,斐波那契数列)
//
// @Author: Brisa
// @Date: 2021/8/27
// @Description: 栈的应用——【括号匹配】、【表达式求值】、【递归】
// 补充:此处是用的顺序栈
//
#include<stdio.h>
#include<string.h>
#define MaxSize 10 //定义栈中元素的最大个数
#define ElemType char
typedef struct {
ElemType data[MaxSize]; //静态数组存放栈中元素
int top; //栈顶指针,一般来说存放数组的下标
}SeqStack;
/*函数声明*/
void InitStack(SeqStack& S); //1.初始化栈
bool StackEmpty(SeqStack S); //2.判空
bool Push(SeqStack& S, ElemType x); //3.入栈
bool Pop(SeqStack& S, ElemType& x); //4.出栈
/*基本操作*/
//1.初始化栈
void InitStack(SeqStack& S) {
S.top = -1; //初始化栈顶指针为-1
}
//2.判空
bool StackEmpty(SeqStack S) {
return (S.top == -1);
}
//3.入栈操作:新元素入栈(先加再存)
bool Push(SeqStack& S, ElemType x) {
if (S.top == MaxSize - 1) //栈满,报错
return false;
S.data[++S.top] = x; //栈顶指针+1,栈顶元素入栈
return true;
}
//4.出栈操作:栈顶元素出栈(先取再减)
bool Pop(SeqStack& S, ElemType& x) {
if (S.top == -1) //栈空,报错
return false;
x = S.data[S.top--]; //栈顶元素出栈,栈顶指针-1
return true;
}
/*栈的应用*/
//1.括号匹配
bool BracketMatch(char str[], int length){
SeqStack S;
InitStack(S);
for(int i = 0; i < length; i++){
if(str[i]=='(' || str[i]=='[' || str[i]=='{')//扫描到左括号,入栈
Push(S, str[i]);
else{//扫描到右括号
if(StackEmpty(S)) //栈空
return false; //栈空,匹配失败
else{//栈非空
ElemType topElem;
Pop(S, topElem); //栈顶元素出栈
//左右括号不匹配,匹配失败
if(str[i]==')' && topElem!='(')
return false;
if(str[i]==']' && topElem!='[')
return false;
if(str[i]=='}' && topElem!='{')
return false;
}
}
}
/*
* 括号数组遍历已完成:
* 1.若此时栈非空,左括号单身,匹配失败
* 2.若此时栈空,则匹配成功
* */
return StackEmpty(S);
}
void TestBracketMatch(){
char s1[] = {'(','[','{','}','(',')',']',')'}; //成功匹配
char s2[] = {'{','[','(',')','}',']','(',')'}; //匹配失败
if (BracketMatch(s1, 8)) //length是字符串的长度
printf("匹配成功!\n");
else
printf("匹配失败!\n");
if (BracketMatch(s2, 8))
printf("匹配成功!\n");
else
printf("匹配失败!\n");
}
//2.表达式求值 前缀,中缀,后缀 【待完成】
//3.递归
int Factorial(int n){
if(n==0 || n==1)
return 1;
else
return n * Factorial(n-1);
}
//4.斐波那契数
int Fib(int n){
if(n == 0)
return 0;
else if(n == 1)
return 1;
else
return Fib(n-1) + Fib(n-2);
}
int main(){
//括号匹配测试
//TestBracketMatch();
//递归测试1 阶乘
int a = Factorial(3);
printf("%d\n",a);
//递归测试2 斐波那契测试
int b = Fib(3);
printf("%d\n",b);
return 0;
}
参考来源:
数据结构代码参考博客
《王道数据结构》