【数据结构】 顺序栈的基本操作 (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 100

typedef 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 100

typedef 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");
                } else
                    printf("顺序栈不为空!\n\n");
            }
                break;
            case 11: {//判满
                Status rFullEmpty = FullEmpty(Sqstack);
                if (rFullEmpty == true) {
                    printf("顺序栈已满!\n\n");
                } else
                    printf("顺序栈不为满!\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;
}

 四、运行结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

模版——函数模版(方法),类模版(容器)

函数模版 之前我们要实现两个变量值的交换要写交换函数&#xff0c; 但是因为交换函数需要把要交换的变量的参数写出来&#xff0c;所以在不同的两个类型的变量值交换的时候我们就要写重载函数&#xff0c;会显得很麻烦&#xff0c;那么我们是不是可以弄个一交换函数的模版&a…

Nacos持久化配置文件到Mysql(全图文).

1. 确保Mysql版本是在8以下&#xff0c;如果是8或者以上请这一步请参考&#xff1a; 最直接有效的解决nacos配置mysql8.0以上版本后无法启动的问题_nacos 8848端口 和mysql冲突-CSDN博客https://blog.csdn.net/qq_42758288/article/details/108967808 2.初始化数据库在Mysql&a…

Linux下安装 Redis7

Linux下安装 Redis7 三、Linux下安装 Redis7【redis-7.2.4.tar.gz】3.1.下载redis的安装包3.1.1.手动下载Redis压缩包并上传【redis-7.2.4.tar.gz】3.1.2.wget工具下载redis-7.2.4.tar.gz 3.2.将安装包进行解压缩3.3.进入redis的安装包3.4.检查是否有gcc 环境3.5.编译和安装并指…

自然语言处理--概率最大中文分词

自然语言处理附加作业--概率最大中文分词 一、理论描述 中文分词是指将中文句子或文本按照语义和语法规则进行切分成词语的过程。在中文语言中&#xff0c;词语之间没有明显的空格或标点符号来分隔&#xff0c;因此需要通过分词工具或算法来实现对中文文本的分词处理。分词的…

大型语言模型基础知识的可视化指南

直观分解复杂人工智能概念的工具和文章汇总 如今&#xff0c;LLM&#xff08;大型语言模型的缩写&#xff09;在全世界都很流行。没有一天不在宣布新的语言模型&#xff0c;这加剧了人们对错过人工智能领域的恐惧。然而&#xff0c;许多人仍在为 LLM 的基本概念而苦苦挣扎&…

操作系统导论-课后作业-ch14

1. 代码如下&#xff1a; #include <stdio.h> #include <stdlib.h>int main() {int *i NULL;free(i);return 0; }执行结果如下&#xff1a; 可见&#xff0c;没有任何报错&#xff0c;执行完成。 2. 执行结果如下&#xff1a; 3. valgrind安装使用参考&a…

数据结构(Chapter Two -03)—线性表的链式表示

在这一部分&#xff08;数据结构(Chapter Two -01)—线性表及顺序表-CSDN博客&#xff09;里面&#xff0c;我们知道线性表包括顺序表和链表结构。前面写了顺序表的基本操作&#xff0c;那这部分就写一写线性表叭&#xff01; 链表特点&#xff1a;不需要使用地址连续的存储单…

【Flink-1.17-教程】-【四】Flink DataStream API(7)输出算子(Sink)

【Flink-1.17-教程】-【四】Flink DataStream API&#xff08;7&#xff09;输出算子&#xff08;Sink&#xff09; 1&#xff09;连接到外部系统2&#xff09;输出到文件3&#xff09;输出到 Kafka4&#xff09;输出到 MySQL&#xff08;JDBC&#xff09;5&#xff09;自定义 …

2024年第十二届亚洲机械与材料工程国际会议(ACMME 2024)即将召开!

时间&#xff1a;2024年6月14-17日 地点&#xff1a;日本京都先端科学大学太秦校区 会议官网&#xff1a;第11届ACMME |日本京都 2024年第十二届亚洲机械与材料工程会议 &#xff08;ACMME 2024&#xff09;将于2024年6月14日-17日在日本京都先端科学大学召开。亚洲机械与材料…

STL第二讲

第二讲 视频标准库源码版本&#xff1a;gnu c 2.9.1/4.9/Visual C OOP vs GP GP是将datas与methods分开&#xff0c;OOP相反&#xff1b; 为什么list不能使用全局的sort&#xff1f; 因为sort源代码&#xff1a; *(first (last - first)/2) // 此迭代器只能是随机访问迭代…

Jedis(一)与Redis的关系

一、Jedis介绍&#xff1a; 1、背景&#xff1a; Jedis是基于Java语言的Redis的客户端&#xff0c;Jedis Java Redis。Redis不仅可以使用命令来操作&#xff0c;现在基本上主流的语言都有API支持&#xff0c;比如Java、C#、C、PHP、Node.js、Go等。在官方网站里有一些Java的…

多维时序 | Matlab实现GWO-TCN-Multihead-Attention灰狼算法优化时间卷积网络结合多头注意力机制多变量时间序列预测

多维时序 | Matlab实现GWO-TCN-Multihead-Attention灰狼算法优化时间卷积网络结合多头注意力机制多变量时间序列预测 目录 多维时序 | Matlab实现GWO-TCN-Multihead-Attention灰狼算法优化时间卷积网络结合多头注意力机制多变量时间序列预测效果一览基本介绍程序设计参考资料 效…

如何自己制作一个属于自己的小程序?

在这个数字化时代&#xff0c;小程序已经成为了我们生活中不可或缺的一部分。它们方便快捷&#xff0c;无需下载安装&#xff0c;扫一扫就能使用。如果你想拥有一个属于自己的小程序&#xff0c;不论是为了个人兴趣&#xff0c;还是商业用途&#xff0c;都可以通过编程或者使用…

VisualODX——ODX数据自动转换工具 加快开发进度

在创建ODX数据库的过程中&#xff0c;我们需要录入大量的数据以及应对多种数据格式。这不仅费时费力&#xff0c;而且还需很高的人力成本&#xff0c;且其错误率也非常高&#xff0c;从而导致开发速度缓慢、效率低下。基于多年的汽车行业诊断经验&#xff0c;我们开发了VisualO…

SpringBoot+Vue充电桩管理系统 附带详细运行指导视频

文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码1. 分页获取预约数据代码2.保存预约信息代码3.修改订单状态代码 一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBootVue框架开发的充电桩管理系统。首先&…

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

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

行测-判断:3.定义判断

行测-判断&#xff1a;3.定义判断 每道题先给出一个概念的定义&#xff0c;然后分别列出四种情况&#xff0c;要求报考者严格依据定义选出一个最符合或者最不符合该定义的答案。 A 1. 读得准 1.1 关键词&#xff08;主体&#xff0c;客体&#xff09; A B C&#xff0c;C选项…

2024年护眼台灯选购指南▏好视力、书客、欧普值得购买吗?

最近&#xff0c;护眼台灯备受关注&#xff0c;许多博主纷纷推崇。考虑到孩子即将放寒假&#xff0c;市场上的产品琳琅满目&#xff0c;因此我决定认真研究一番&#xff0c;辨别其中的劣质和精品。我选择了市场口碑较好的三款产品&#xff0c;进行了深入评估&#xff0c;主要从…

Tuya MiniApp 设计指南

一. 简介 小程序以其轻量、便捷的特性&#xff0c;在移动端 App 中被越来越广泛地使用。Tuya 作为物联网生态的头部 App 企业之一&#xff0c;开放 Tuya MiniApp 开发能力&#xff0c;以帮助开发者更好地服务用户。 对于开发者&#xff0c;Tuya MiniApp 以全新的开放模式&…

【Linux】文件周边001之系统文件IO

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.C语言文件IO 1.1…