【数据结构】 顺序栈的基本操作 (C语言版)

目录

一、顺序栈

1、顺序栈的定义:

2、顺序栈的优缺点

二、顺序栈的基本操作算法(C语言)   

1、宏定义

 2、创建结构体

3、顺序栈的初始化 

4、顺序栈的入栈

5、顺序栈的出栈

6、取栈顶元素

7、栈的遍历输出

8、顺序栈的判空

9、顺序栈的判满

 10、求顺序栈长度

11、顺序栈的清空

12、顺序栈的销毁

13、数制转换

 14、括号匹配

三、顺序栈的基本操作完整代码(C语言)

 四、运行结果


一、顺序栈

1、顺序栈的定义:

顺序栈是由一维数组实现的栈,其中栈底元素的下标为0,栈顶元素的下标为n-1(n为数组大小),栈的大小在创建时确定,且在栈的生命周期内保持不变。

2、顺序栈的优缺点

顺序栈的优点:

  1. 空间利用率高:由于数组的大小在创建时确定,因此可以预先分配足够的空间,避免了频繁的内存申请和释放操作,提高了空间利用率。
  2. 存取速度快:由于栈元素在内存中连续存储,因此可以根据下标直接访问栈底元素和栈顶元素,存取速度快。
  3. 方便进行动态扩展:在某些情况下,可以在栈外再开辟一块内存空间,将栈的大小动态扩展,从而方便处理大规模的数据。

顺序栈的缺点:

  1. 内存浪费:如果预分配的数组大小过大,会造成内存浪费;如果预分配的数组大小过小,则可能会频繁地进行内存申请和释放操作,降低性能。
  2. 不适合处理动态扩展的数据:顺序栈的空间大小在创建时确定,因此无法动态扩展,对于需要处理大规模数据的情况不太适用。
  3. 不便于处理异常情况:如果栈已满而仍需添加元素,会导致栈溢出;如果栈未满而尝试删除元素,会导致栈下溢。这些异常情况的处理较为复杂。

二、顺序栈的基本操作算法(C语言)   

1、宏定义
#define OK 1
#define ERROR 0
#define MAXSIZE 100typedef char SElemType;
typedef int Status;
 2、创建结构体
typedef struct {SElemType *base;SElemType *top;int stacksize;
} SqStack;
3、顺序栈的初始化 
//初始化
Status InitStack(SqStack &S) {S.base = new SElemType[MAXSIZE];if (!S.base)return 0;S.top = S.base;S.stacksize = MAXSIZE;return OK;
}
4、顺序栈的入栈
//进栈
Status Push(SqStack &S, SElemType e) {if (S.top - S.base == S.stacksize)return 0;*S.top++ = e;return OK;
}
5、顺序栈的出栈
//出栈
Status Pop(SqStack &S, SElemType &e) {if (S.top == S.base)return 0;e = *(--S.top);return OK;
}
6、取栈顶元素
//获取栈顶元素
Status Top(SqStack &S, SElemType &e) {if (S.top == S.base)return ERROR;e = *(S.top - 1);return OK;
}
7、栈的遍历输出
//栈的遍历输出
void printStack(SqStack S) {printf("现在栈内元素为:");SElemType *p = S.base;while (p != S.top) {printf("%c ", *p);p++;}printf("\n");
}
8、顺序栈的判空
//判空S.top == S.base
Status StackEmpty(SqStack S) {if (S.top == S.base) {return true;} else {return false;}
}
9、顺序栈的判满
//判满
Status FullEmpty(SqStack S) {if (S.top - S.base == S.stacksize) {return true;} else {return false;}
}
 10、求顺序栈长度
//求顺序栈长度
Status StackLength(SqStack S) {return S.top - S.base;
}
11、顺序栈的清空
//清空
Status ClearStack(SqStack &S) {S.top = S.base;return OK;
}
12、顺序栈的销毁

//销毁
Status DestroyStack(SqStack &S) {if (S.base) {delete S.base;S.stacksize = 0;S.top = S.base = NULL;}return OK;
}
13、数制转换
//数制转换
void conversion(int N) {SqStack S;InitStack(S);char e;while (N) {Push(S, N % 8);N = N / 8;}while (!StackEmpty(S)) {Pop(S, e);printf("%d", e);}
}
 14、括号匹配
//括号匹配
Status Matching() {SqStack S;InitStack(S);SElemType ch, x;Status flag = 1;printf("请输入需要匹配的括号(以#结束):\n");//char ch = getche();scanf("%c", &ch);while (ch != '#' && flag) {switch (ch) {case '(':case '[':Push(S, ch);break;case ')':if (!StackEmpty(S) && GetTop(S) == '(') {Pop(S, x);} else {flag = 0;}break;case ']':if (!StackEmpty(S) && GetTop(S) == '[') {Pop(S, x);} else {flag = 0;}break;}//ch = getche();scanf("%c", &ch);}if (StackEmpty(S) && flag) {return true;} else {return false;}
}

三、顺序栈的基本操作完整代码(C语言)

#include <stdio.h>
#include <conio.h>//getchae()#define OK 1
#define ERROR 0#define MAXSIZE 100typedef char SElemType;
typedef int Status;//创建结构体
typedef struct {SElemType *base;SElemType *top;int stacksize;
} SqStack;//初始化
Status InitStack(SqStack &S) {S.base = new SElemType[MAXSIZE];if (!S.base)return 0;S.top = S.base;S.stacksize = MAXSIZE;return OK;
}//进栈
Status Push(SqStack &S, SElemType e) {if (S.top - S.base == S.stacksize)return 0;*S.top++ = e;return OK;
}//求顺序栈长度
Status StackLength(SqStack S) {return S.top - S.base;
}//出栈
Status Pop(SqStack &S, SElemType &e) {if (S.top == S.base)return 0;e = *(--S.top);return OK;
}//获取栈顶元素
Status Top(SqStack &S, SElemType &e) {if (S.top == S.base)return ERROR;e = *(S.top - 1);return OK;
}//获取栈顶元素
SElemType GetTop(SqStack &S) {if (S.top == S.base)return ERROR;return *(S.top - 1);
}//栈的遍历输出
void printStack(SqStack S) {printf("现在栈内元素为:");SElemType *p = S.base;while (p != S.top) {printf("%c ", *p);p++;}printf("\n");
}//清空
Status ClearStack(SqStack &S) {S.top = S.base;return OK;
}//销毁
Status DestroyStack(SqStack &S) {if (S.base) {delete S.base;S.stacksize = 0;S.top = S.base = NULL;}return OK;
}
//Status DestoryStack(SqStack &S) {
//    if (S.base) {
//        delete S.base;
//        S.stacksize = 0;
//        S.base = S.top = NULL;
//    }
//    return OK;
//}//判空S.top == S.base
Status StackEmpty(SqStack S) {if (S.top == S.base) {return true;} else {return false;}
}//判满
Status FullEmpty(SqStack S) {if (S.top - S.base == S.stacksize) {return true;} else {return false;}
}//数制转换
void conversion(int N) {SqStack S;InitStack(S);char e;while (N) {Push(S, N % 8);N = N / 8;}while (!StackEmpty(S)) {Pop(S, e);printf("%d", e);}
}//括号匹配
Status Matching() {SqStack S;InitStack(S);SElemType ch, x;Status flag = 1;printf("请输入需要匹配的括号(以#结束):\n");//char ch = getche();scanf("%c", &ch);while (ch != '#' && flag) {switch (ch) {case '(':case '[':Push(S, ch);break;case ')':if (!StackEmpty(S) && GetTop(S) == '(') {Pop(S, x);} else {flag = 0;}break;case ']':if (!StackEmpty(S) && GetTop(S) == '[') {Pop(S, x);} else {flag = 0;}break;}//ch = getche();scanf("%c", &ch);}if (StackEmpty(S) && flag) {return true;} else {return false;}
}//功能菜单
Status choice() {printf("==================================\n");printf("         顺序栈操作功能菜单        \n");printf("1、进栈  2、出栈  3、获取栈顶元素   \n");printf("4、清空  5、销毁   6、批量进栈     \n");printf("7、打印栈内元素     8、数制转换    \n");printf("9、括号匹配  10、判空  11、判满    \n");printf("12、顺序栈的长度    13退出程序     \n");printf("==================================\n");return 0;
}int main() {SqStack Sqstack;//初始化Status rInitStack = InitStack(Sqstack);if (rInitStack == OK) {printf("顺序栈初始化成功!\n");} else {printf("顺序栈初始化失败!\n");}while (1) {//功能菜单choice();int flag;printf("请输入所需的功能编号:");scanf("%d", &flag);switch (flag) {case 1: {//进栈SElemType Pushdata;printf("请输入插入元素(请在英文状态下输入例如:a): \n");getchar();scanf("%c", &Pushdata);Status rPush = Push(Sqstack, Pushdata);if (rPush == OK) {printf("向顺序栈进栈%c成功!\n\n", Pushdata);} else {printf("向顺序栈进栈失败!\n\n");}}break;case 2: {//出栈SElemType popData;Status rPop = Pop(Sqstack, popData);if (rPop == OK) {printf("向顺序栈出栈%c成功!\n\n", popData);} else {printf("向顺序栈出栈失败!\n\n");}}break;case 3: {//获取栈顶元素SElemType topData;Status rTop = Top(Sqstack, topData);if (rTop == OK) {printf("向顺序栈获取栈顶元素:%c  。\n\n", topData);} else {printf("向顺序栈获取栈顶元素失败!\n\n");}//获取栈顶元素
//                Status rGetTop = GetTop(Sqstack);
//                if (rGetTop == OK) {
//                    printf("向顺序栈获取栈顶元素:%d\n", topData);
//                } else {
//                    printf("向顺序栈获取栈顶元素失败!\n");
//                }}break;case 4: { //清空Status rClearStack = ClearStack(Sqstack);if (rClearStack == OK) {printf("顺序栈清空成功!\n\n");} else {printf("顺序栈清空失败!\n\n");}}break;case 5: {//销毁Status rDestroyStack = DestroyStack(Sqstack);if (rDestroyStack == OK) {printf("顺序栈销毁成功!\n\n");} else {printf("顺序栈销毁失败!\n\n");}}break;case 6: {//批量插入int on;printf("请输入想要插入的元素个数:\n");scanf("%d", &on);SElemType array[on];for (int i = 1; i <= on; i++) {getchar();printf("向顺序栈第%d个位置插入元素为:", (i));scanf("%c", &array[i]);}for (int i = 1; i <= on; i++) {Status rPush = Push(Sqstack, array[i]);if (rPush == OK) {printf("向顺序栈第%d个位置插入元素%c成功!\n", i, array[i]);} else {printf("向顺序栈第%d个位置插入元素%c失败!\n", i, array[i]);}}}break;case 7: {//打印栈内元素printStack(Sqstack);}break;case 8: {//数制转换int N;printf("请输入1个非负十进制数:");scanf("%d", &N);printf("十进制数:%d 。\n", N);printf("转换为八进制数为:");conversion(N);printf("\n");}break;case 9: {//括号匹配Status rMatch = Matching();if (rMatch == true) {printf("括号匹配成功!\n\n");} else {printf("括号匹配不成功!\n\n");}}break;case 10: {//判空Status rStackEmpty = StackEmpty(Sqstack);if (rStackEmpty == true) {printf("顺序栈为空栈!\n\n");} elseprintf("顺序栈不为空!\n\n");}break;case 11: {//判满Status rFullEmpty = FullEmpty(Sqstack);if (rFullEmpty == true) {printf("顺序栈已满!\n\n");} elseprintf("顺序栈不为满!\n\n");}break;case 12: {//顺序栈的长度Status length = StackLength(Sqstack);printf("顺序栈的长度为:%d 。\n\n", length);}break;case 13: {//退出程序return 0;}break;default: {printf("输入错误,无此功能,请检查输入:\n\n");}}}return 1;
}

 四、运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/643588.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(19)-Fiddler精选插件扩展安装,将你的Fiddler武装到牙齿

1.简介 Fiddler本身的功能其实也已经很强大了&#xff0c;但是Fiddler官方还有很多其他扩展插件功能&#xff0c;可以更好地辅助Fiddler去帮助用户去开发、测试和管理项目上的任务。Fiddler已有的功能已经够我们日常工作中使用了&#xff0c;为了更好的扩展Fiddler&#xff0c…

Vue3 Suspense

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…

windows cmd命令行隐藏窗口后台启动运行程序,开机自启

隐藏窗口后台启动运行 我的目录结构 start.bat echo off if "%1" "h" goto begin mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit :begin :: cd %~dp0 call shutdown.bat jre…

一文读懂:D3.js的前世今生,以及与echarts的对比

D3.js&#xff08;Data-Driven Documents&#xff09;是一种用于创建动态、交互式数据可视化的JavaScript库。它通过使用HTML、CSS和SVG等Web标准&#xff0c;将数据与文档结合&#xff0c;使得数据可以以一种直观和易于理解的方式进行呈现。D3.js的重要性在于它赋予了开发者更…

【GitHub项目推荐--不错的Rust开源项目】【转载】

01 Rust 即时模式 GUI 库 egui 是一个简单、快速且高度可移植的 Rust 即时模式 GUI 库&#xff0c;可以轻松地将其集成到你选择的游戏引擎中&#xff0c;旨在成为最易于使用的 Rust GUI 库&#xff0c;以及在 Rust 中制作 Web 应用程序的最简单方法。 项目地址&#xff1a;ht…

【面试突击】微信亿级朋友圈的社交系统设计

微信亿级朋友圈的社交系统设计 先来说一下业务需求吧&#xff1a; 每个用户可以发朋友圈&#xff0c;可以点赞&#xff0c;评论可以设置权限&#xff0c;不看某些人朋友圈、不让某些人看你的朋友圈可以刷朋友圈中其他人的动态 对于这样的系统设计&#xff0c;主要从业务来考虑…

gin中使用validator做参数校验

在web开发中对请求参数进行校验&#xff0c;通常在代码中定义与请求参数相对应的模型&#xff08;结构体&#xff09;&#xff0c;借助模型绑定快捷地解析请求中的参数&#xff0c;例如 gin 框架中的Bind和ShouldBind系列方法。 gin框架使用github.com/go-playground/validato…

uniapp css样式穿透

目录 前言css样式穿透方法不加css样式穿透的代码加css样式穿透的代码不加css样式穿透的代码 与 加css样式穿透的代码 的差别参考 前言 略 css样式穿透方法 使用 /deep/ 进行css样式穿透 不加css样式穿透的代码 <style>div {background-color: #ddd;} </style>…

用这个技术管理备用电源!同事下巴都惊掉了!

在当今社会&#xff0c;电力供应的可靠性对各个行业的正常运行至关重要。而蓄电池作为备用电源的重要组成部分&#xff0c;其性能和状态的稳定管理成为保障电力系统稳定性的关键环节。 因此&#xff0c;为了有效监测和管理蓄电池&#xff0c;蓄电池监控系统应运而生。 客户案例…

智能机器人与旋量代数(12)

Chapt 4. 旋量代数在机器人学中的应用 4.1 串联机器人正运动学的指数积(PoE, Product of Exponetial)公式 4.1.1 回顾&#xff1a;机器人正运动学的Denavit-Hartenberg (D-H)参数公式 D-H 建模法: D-H 建模方法是由 Denavit 和 Hartenberg (ASME, 1955) 提出的一种建模方法&…

如何高效挖掘Web漏洞?

简介 SRC漏洞平台&#xff1a;安全应急响应中心&#xff08;SRC, Security Response Center&#xff09;&#xff0c;是企业用于对外接收来自用户发现并报告的产品安全漏洞的站点。说白了&#xff0c;就是连接白帽子和企业的平台&#xff0c;你去合法提交漏洞给他们&#xff0…

C#中的委托概念以及例子

在C#中&#xff0c;什么是委托&#xff08;Delegate&#xff09;&#xff1f;请简要说明委托的概念&#xff0c;并提供一个简单的示例说明如何使用委托。 答案&#xff1a; 委托的概念&#xff1a; 委托是一种类型&#xff0c;它允许将方法作为参数传递&#xff0c;使得可以…

Leetcode—24. 两两交换链表中的节点【中等】

2023每日刷题&#xff08;八十七&#xff09; Leetcode—24. 两两交换链表中的节点 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x),…

Redis(发布订阅、事务、redis整合springboot、集成 Spring Cache)

目录 一.redis的发布订阅 1、什么 是发布和订阅 2、Redis的发布和订阅 3、发布订阅的代码实现 二.Redis事务 1.事务简介 1、在事务执行之前 如果监听的key的值有变化就不能执行 2、在事务执行之前 如果监听的key的值没有变化就能执行 3、Exec之前就出现错误 4、Exec之…

《面试专题-----经典高频面试题收集四》解锁 Java 面试的关键:深度解析并发编程进阶篇高频经典面试题(第四篇)

目录 第六章&#xff08;并发编程进阶&#xff09;1.并发编程的三要素分别解释一下&#xff0c;举个简单的例子2.说下你知道的调度算法&#xff0c;比如进程间的调度3.常见的线程间的调度算法是怎么样的&#xff0c;java是哪种4.日常开发中用过java中的哪些锁&#xff1f;分别解…

Centos7 两种方式安装 MySQL5.7 步骤 yum 、本地 tar 文件

一、使用 yum 源方式安装 1、卸载系统自带 mariadb MariaDB Server 是最流行的开源 关系型数据库 之一。它由 MySQL 的原始开发者制作&#xff0c;并保证保持开源。 在 CentOS 7 中默认安装有 MariaDB 可忽略&#xff0c;安装完成之后可以直接覆盖掉 MariaDB。 查看并卸载系统…

如何在 Spring Boot 中配置日志记录?

在Spring Boot中配置日志记录是一项关键任务&#xff0c;因为良好的日志记录是应用程序开发和维护的必要组成部分。Spring Boot采用了一种灵活且强大的方式来管理日志&#xff0c;允许开发人员使用不同的日志框架&#xff0c;并提供了易于配置的选项。下面详细介绍在Spring Boo…

新概念英语第二册(39) 上

【New words and expressions】生词和短语&#xff08;10&#xff09; operation n. 手术 successful adj. 成功的 following adj. 下一个 patient n. 病人 alone …

openssl3.2/test/certs - 004 - cross root and root cross cert

文章目录 openssl3.2/test/certs - 004 - cross root and root cross cert概述笔记END openssl3.2/test/certs - 004 - cross root and root cross cert 概述 索引贴 openssl3.2 - 官方demo学习 - test - certs 笔记 // \file my_openssl_linux_log_doc_004.txt // openssl…

【Java 设计模式】行为型之状态模式

文章目录 1. 定义2. 应用场景3. 代码实现结语 状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;用于通过将对象的行为封装到不同的状态类中&#xff0c;使得对象在不同的状态下具有不同的行为。状态模式允许对象在内部状态发生改变时改变其行为…