共享栈的简单实现(C语言)
共享栈的简单实现(C语言)
- 认识共享栈
- 基本操作
- 入栈
- 出栈
- 读取栈顶元素
- 输出栈
- 定义
- 初始化
- 完整代码
认识共享栈
共享栈的本质就是一个数组存放两个栈,公用一个数组空间。由于顺序栈是创建时就固定了空间大小,而这些空间通常不会一下用完,共享栈可以提高空间的利用率。
通过设置两个栈顶游标即可很容易得把数组空间分成两个部分来操作管理。
基本操作
由于有两个栈,所以操作函数要写两遍分别对不同的栈进行操作。在主函数调用的时候可以使用函数指针(链接: C语言指针入门.)方便操作。
入栈
// 入栈
// A栈
bool PushA(ShStack *S, ElemType e){if((*S).topA + 1 == (*S).topB) return false; // 栈满,返回错误(*S).data[++(*S).topA] = e; // 数据存入return true;
}
// B栈
bool PushB(ShStack *S, ElemType e){// (*S).topA 和 S->topA 等价if(S->topA + 1 == S->topB) return false; // 栈满,返回错误S->data[--S->topB] = e;return true;
}
出栈
// 出栈
// A栈
bool PopA(ShStack *S, ElemType *e){if(S->topA == -1) return false; //判空*e = S->data[S->topA--];return true;
}
// B栈
bool PopB(ShStack *S, ElemType *e){if(S->topB == MaxSize) return false; //判空*e = S->data[S->topB++];return true;
}
读取栈顶元素
// 读取栈顶元素
void GetTop(ShStack S, ElemType *top_A, ElemType *top_B){ // 同时获取两个栈的栈顶if(S.topA == -1){ // A栈判空printf("StackA is empty!\n");}else{*top_A = S.data[S.topA]; // 获取栈顶数据,通过指针返回}if(S.topB == MaxSize){ // B栈判空printf("StackB is empty!\n");}else{*top_B = S.data[S.topB]; // 获取栈顶数据,通过指针返回}
}
输出栈
// 输出栈
void PrintStack(ShStack S){int a = S.topA + 1;int b = MaxSize - S.topB;if(S.topA == -1){ // A栈判空,,printf("StackA is empty!\n");}else{printf("StackA: ");while(a--){printf("%d ", S.data[S.topA--]);}printf("\n");}if(S.topB == MaxSize){ // B栈判空printf("StackB is empty!\n");}else{printf("StackB: ");while(b--){printf("%d ", S.data[S.topB++]);}printf("\n");}
}
定义
typedef struct{ElemType data[MaxSize]; // 数据域int topA; // A栈栈顶游标int topB; // B栈栈顶游标
}ShStack;
初始化
// 初始化
void InitStack(ShStack *S){ // 初始化栈顶游标(*S).topA = -1;(*S).topB = MaxSize;
}
完整代码
// 共享栈
#include<stdio.h>
#include<stdbool.h>#define MaxSize 50
typedef int ElemType;typedef struct{ElemType data[MaxSize]; // 数据域int topA; // A栈栈顶游标int topB; // B栈栈顶游标
}ShStack;// 初始化
void InitStack(ShStack *S){ // 初始化栈顶游标(*S).topA = -1;(*S).topB = MaxSize;
}// 创建栈 多元素入栈// 入栈
// A栈
bool PushA(ShStack *S, ElemType e){if((*S).topA + 1 == (*S).topB) return false; // 栈满,返回错误(*S).data[++(*S).topA] = e; // 数据存入return true;
}
// B栈
bool PushB(ShStack *S, ElemType e){// (*S).topA 和 S->topA 等价if(S->topA + 1 == S->topB) return false; // 栈满,返回错误S->data[--S->topB] = e;return true;
}// 出栈
// A栈
bool PopA(ShStack *S, ElemType *e){if(S->topA == -1) return false; //判空*e = S->data[S->topA--];return true;
}
// B栈
bool PopB(ShStack *S, ElemType *e){if(S->topB == MaxSize) return false; //判空*e = S->data[S->topB++];return true;
}// 读取栈顶元素
void GetTop(ShStack S, ElemType *top_A, ElemType *top_B){ // 同时获取两个栈的栈顶if(S.topA == -1){ // A栈判空printf("StackA is empty!\n");}else{*top_A = S.data[S.topA]; // 获取栈顶数据,通过指针返回}if(S.topB == MaxSize){ // B栈判空printf("StackB is empty!\n");}else{*top_B = S.data[S.topB]; // 获取栈顶数据,通过指针返回}
}// 输出栈
void PrintStack(ShStack S){int a = S.topA + 1;int b = MaxSize - S.topB;if(S.topA == -1){ // A栈判空,,printf("StackA is empty!\n");}else{printf("StackA: ");while(a--){printf("%d ", S.data[S.topA--]);}printf("\n");}if(S.topB == MaxSize){ // B栈判空printf("StackB is empty!\n");}else{printf("StackB: ");while(b--){printf("%d ", S.data[S.topB++]);}printf("\n");}
}int main(){ShStack S; // 声明int status; // 操作码ElemType e, eA, eB; // 元素int len; // 长度char AorB; // 用于判断操作栈A或栈Bbool (*push)(ShStack*, ElemType); // Push函数类型的函数指针bool (*pop)(ShStack*, ElemType*); // pop函数类型的函数指针InitStack(&S); // 初始化 while(1){printf("Please enter a status code:\n1.CreateStack 2.Push 3.Pop\n");printf("4.GetTop 5.PrintStack 0.Exit\n");scanf("%d", &status);if(status == 0) break;switch (status){case 1: // 创建栈printf("Please enter the stack(A or B) you want to operate and the length you want to create.\n");scanf(" %c", &AorB);getchar();scanf(" %d", &len); if(AorB == 'A'){push = PushA;printf("Please enter %d elements one by one in order!\n", len);while(len--){scanf("%d", &e); // 记录数据push(&S, e); // 使用push函数指针调用对应函数}PrintStack(S);}else if(AorB == 'B'){push = PushB;printf("Please enter %d elements one by one in order!\n", len);while(len--){scanf("%d", &e); // 记录数据push(&S, e); // 使用push函数指针调用对应函数}PrintStack(S);}else{printf("Please select whether you want to operate on stack A or stack B!\n");} break;case 2: // 入栈printf("Please enter the stack(A or B) you want to operate and the element value you want to push\n");scanf(" %c", &AorB);getchar();scanf(" %d", &e);if(AorB == 'A'){push = PushA; // 函数指针指向B栈的入栈函数}else if(AorB == 'B'){push = PushB; // 函数指针指向B栈的入栈函数}else{printf("Please select whether you want to push on stack A or stack B!\n");}if(push(&S, e)){ // 使用函数指针调用对应函数printf("Stack%c: Push successfully!\n", AorB);}else{printf("Stack%c: Failed to Push! Maybe the stack overflowed.\n", AorB);}PrintStack(S);break;case 3: // 出栈printf("please enter the stack(A or B) you want to operate\n");scanf(" %c", &AorB);if(AorB == 'A'){pop = PopA; // 函数指针指向A栈的出栈函数}else if(AorB == 'B'){pop = PopB; // 函数指针指向B栈的出栈函数}else{printf("Please select whether you want to pop on stack A or stack B!");}if(pop(&S, &e)){ // 使用函数指针调用对应函数printf("Stack%c: Element value %d Pop successfully\n", AorB, e);}else{printf("Stack%c: Failed to Pop!\n", AorB);}PrintStack(S);break;case 4: // 读取栈顶元素GetTop(S, &eA, &eB);printf("The StackA top elem is %d\n", eA);printf("The StackB top elem is %d\n", eB);break;case 5: // 输出表PrintStack(S);break;default:printf("Error!\n");break;}}
}
运行展示
共享栈的简单实现(C语言)相关推荐
- 【数据结构】共享栈详解 判断共享栈满条件栈顶指针变化详解记忆方法例题
摘要:简单易懂,详细地介绍共享栈概念,指针,判断共享栈栈满条件以及记忆方法等 目录 共享栈概念 栈顶指针&变化详解 栈顶指针种类的记忆方法 判断栈满条件 判断栈满条件的记忆方法 例题 解题思路 ...
- 用C语言模拟栈(简单实现)
//C语言模拟栈,简单实现 #include <stdio.h> #include <stdlib.h> typedef struct Node node; struct No ...
- (C语言)静态栈编写简单计算器(感悟与详细解析)
C语言数据结构静态栈--计算器的实现 下面我来详细的解释一下我编写的计算器代码.... 有必要先说明一下的是,此代码中含有两个栈:数据栈和算符栈: 数据栈:存放double型数字: 算符栈:存放cha ...
- 【C语言实现共享栈】关于【共享栈】,你知道多少,快来看看吧
目录 一 .共享栈的基本概念 1.定义 2.特点 二.共享栈的表示 三.共享栈的基本操作 1.共享栈的初始化操作 2.共享栈的判空操作 3.共享栈的进栈操作 0号栈进栈 1号栈进栈 4.共享栈的出栈操 ...
- c语言主线程退出子线程,简单了解C语言中主线程退出对子线程的影响
这篇文章主要介绍了简单了解C语言中主线程退出对子线程的影响,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 对于程序来说,如果主进程在子进程还未结束时 ...
- arm64入栈出栈_使用 ARM64 汇编实现共享栈式协程
# 简述 大约在半年以前,我曾经了解过协程的相关实现,也看过腾讯后台开源的协程库`libco`,对其中实现协程相关的汇编有很深的印象(`libco`适配的是 x86 平台).接受了这样的思想,我在自己 ...
- 进程、线程、协程 关于进程、线程、协程,有非常详细和丰富的博客或者学习资源,我不在此做赘述,我大致在此介绍一下这几个东西。 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。
进程.线程.协程 关于进程.线程.协程,有非常详细和丰富的博客或者学习资源,我不在此做赘述,我大致在此介绍一下这几个东西. 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度. 线程 ...
- 对数据结构中共享栈减少上溢的理解
目录 共享栈的定义 为何使用共享栈 栈满 后记 共享栈的定义 简单说就是两栈共用一片连续内存空间. (王道书定义:)共享栈就是让两个顺序栈(一片连续内存,栈就是顺序栈)共享一个一维数组空间,将两个栈的 ...
- PTA 基础编程题目集 7-12 两个数的简单计算器 C语言
PTA 基础编程题目集 7-12 两个数的简单计算器 C语言 本题要求编写一个简单计算器程序,可根据输入的运算符,对2个整数进行加.减.乘.除或求余运算.题目保证输入和输出均不超过整型范围. 输入格式 ...
最新文章
- 《慕客网:IOS基础入门之Foundation框架初体验》学习笔记 二 NSMutableString
- 二逼平横树——线段树套平衡树
- 中英文怎么算 字符长度_如何将混合了中英文及不同数量空格的文本,快速拆分成多列...
- java main 声明_Java中main方面面试题
- Diango博客--12.开发 Django 博客文章阅读量统计功能
- 商用服务器系统比较好,商用服务器操作系统都用哪种
- 华为明日发布鸿蒙整体战略;京东宣告全面向技术转型;Kotlin 1.3.60 发布 | 极客头条...
- php单元格字体颜色,PHPExcel API接口用法大全,按模板导入excel,美化excel,导出图片,设置单元格字体颜色背景色边框,合并单元格,设置行高列宽...
- 深入浅出mysql_深入浅出mysql索引
- NHibernate.Cfg.HibernateConfigException
- 我对Asp.net页面一系列执行过程的认识
- linux pagecache与内存占用
- 计算机对电器的影响论文,突然断电到底伤不伤电器:这是答案
- 小米4A 32电视通过TTL方式ROOT的方法
- w ndows键盘哪个键,B.O.W航世的蓝牙键盘的BackSpace键失灵怎么办?Windows修改键盘映射帮到你。...
- CHM转换PDF好轻松
- 【数论】Pollard-Rho 算法总结
- 土木/岩土期刊版面费/审稿费统计列表
- 通过access口加vlan标签吗_如何理解:“Access端口加入的VLAN必须已经存在并且不能是VLAN 1;Hybrid端口加入的VLAN必须已经存在;Trun...
- 如何在Win11调出IE11浏览器?