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

news2024/10/5 21:21:41

目录

一、顺序栈

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;
}

 四、运行结果

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

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

相关文章

记一次Flink通过Kafka写入MySQL的过程

一、前言 总体思路&#xff1a;source -->transform -->sink ,即从source获取相应的数据来源&#xff0c;然后进行数据转换&#xff0c;将数据从比较乱的格式&#xff0c;转换成我们需要的格式&#xff0c;转换处理后&#xff0c;然后进行sink功能&#xff0c;也就是将数…

Linux:vim的相关知识

目录 vim 是一个较为常见的编译文件的命令操作。 三种模式的区分的作用如下&#xff1a; 命令模式&#xff1a; 插入模式&#xff1a; 进入插入模式的标志&#xff1a;左下角有INSERT 底行模式&#xff1a; 命令模式的常见命令&#xff1a; 底行模式常见命令&#xff1…

解析找不到msvcr110.dll,无法继续支持此代码的多种修复方法

当你在运行某些应用程序或游戏时&#xff0c;可能会遇到"找不到msvcr110.dll无法继续执行"的错误信息&#xff0c;这通常表明系统中缺少某个重要文件。为了解决这个问题&#xff0c;让我们先探讨为什么会发生这种情况。只要了解了&#xff0c;我们才能用更多的方法去…

JAVA 学习 面试(六)数据类型与方法

数据类型 基本数据类型 为什么float3.4报错 3.4 默认是浮点double类型的&#xff0c;如果赋值给float是向下转型&#xff0c;会出现精度缺失&#xff0c;&#xff0c;需要强制转换 Switch支持的数据类型&#xff1f; byte、short、int、char 、 enum 、 String 基本类型与包…

Git的merge和rebase你真的了解吗?

1. 前言 在我们的日常开发中&#xff0c;Git扮演着重要的角色&#xff0c;负责管理代码的版本。分支管理在开发过程中具有显著的影响。通常情况下&#xff0c;我们有生产、预发、测试和开发这几种分支。根据项目的不同阶段&#xff0c;我们会将代码提交到相应的版本上。标准的…

OpenGL ES 实现图像腐蚀、膨胀、边缘检测

前文我们详细讲了图像锐化的基本原理,本文再介绍一下图像基本处理之腐蚀、膨胀和边缘检测,它们在图像处理和计算机视觉领域有着广泛的应用。 图像腐蚀(Image Erosion):用于缩小或消除图像中物体的边界。主要用于去除图像中的小细节、噪声或不规则物体。 实现图像腐蚀的片…

【Android 10】 BatteryController

学习了一下电池的相关模式&#xff0c;也就是它的观察者模式&#xff0c;先附上图 图应该挺清晰的&#xff0c;BatteryControllerImpl就是被观察者&#xff0c;BatteryControllerImpl重写了CallbackController的两个方法用于添加或移除观察者。 void addCallback(T listener);…

编码下的雪景:如何用HTML和JS让雪花在屏幕上舞动

这段时间&#xff0c;全国各地都加入了下雪的队伍当中&#xff0c;看着窗外漫天飞雪&#xff0c;想着我的网站上面也来一场雪吧。正琢磨着如何实现&#xff0c;网上突然蹦出来一段下雪的代码&#xff0c;这不正是我要的么&#xff1f;先来看看效果吧。 效果一 效果二 效果三 要…

7.Feign远程调用

2.Feign远程调用 先来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; 存在下面的问题&#xff1a; •代码可读性差&#xff0c;编程体验不统一 •参数复杂URL难以维护 Feign是一个声明式的http客户端&#xff0c;官方地址&#xff1a;https://github.com/OpenF…

Modbus通信无法正确接收应答的问题处理

问题现象&#xff1a; 现场反馈&#xff0c;modbus网关无法正确读取就地设备的温度信息。使用PC连接就地设备可以正常读取。 问题调查&#xff1a; 拿到末端设备后&#xff0c;故障现象可重复&#xff0c;不过使用PC的USB转485适配器也无法正常读取数据。 如下图&#xff1…

不要为了学习而学习

经常有朋友问我&#xff1a; 老师&#xff0c;从您这里学了很多方法&#xff0c;也一直想要改变自己&#xff0c;但总是没办法坚持下去&#xff0c;怎么办&#xff1f; 这个问题&#xff0c;我也很无奈啊。毕竟我也没办法飞到你身边&#xff0c;手把手把每一步都教给你。&…

万字长文详解Java线程池面试题

王有志&#xff0c;一个分享硬核 Java 技术的互金摸鱼侠 加入 Java 人的提桶跑路群&#xff1a;共同富裕的Java人 今天是《面霸的自我修养》第 6 篇文章&#xff0c;我们一起来看看面试中会问到哪些关于线程池的问题吧。数据来源&#xff1a; 大部分来自于各机构&#xff08;J…

编程入门:五个你必须知道的编程常识

常识1&#xff1a;编程不仅仅是写代码 当我们谈论编程时&#xff0c;大多数人首先想到的是写代码。这是正确的&#xff0c;但并不完整。编程不仅仅是写代码&#xff0c;而是解决问题的一种方式。编程是一种工具&#xff0c;我们使用它来创建能够解决特定问题的产品和服务。 比…

【日常聊聊】自然语言处理的发展

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; 日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 技术进步 应用场景 挑战与前景 伦理和社会影响 实践经验 结语 我的其他博客 前言 自然语言处理&#xff08;NLP&#xf…

iLO 安装中文固件包

前言 安装中文版本的安装包&#xff0c;需要把对应的ilo安装到固定的版本上&#xff0c;ilo的版本是2.70。必须是这个版本&#xff1b; 如果不是这个版本就需要刷到对应的ilo版本 下载对应的固件包。 到这个界面选择文件&#xff0c;然后点击上载。 以上就是刷系统包的步骤。 …

物流实时数仓——概述与准备工作

目录 一、架构设计与技术栈 (一)数仓架构设计 (二)所用技术栈 (三)最终效果 二、关于离线与实时的相关概念 三、实时数仓设计思路 一、架构设计与技术栈 (一)数仓架构设计 (二)所用技术栈 Hadoop 3.3.4 Zookeeper 3.7.1 Kafka 3.3.1 Hbase 2.4.11 Redis 6.0.8 Flink 1.17…

Linux操作系统概念

绪论​&#xff1a; “心灵纯洁的人&#xff0c;生活充满甜蜜和喜悦。——列夫托尔斯泰”&#xff0c;本章的主要内容是介绍了硬件的组成结构冯诺依曼体系结构以及操作系统的概念和操作系统的作用&#xff0c;本章的内容主要是理论他起到承上启下的作用只有理解了操作系统的运行…

基于SpringBoot Vue宠物领养系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

了解面试必会算法Sliding Window 模式的前世今生

大家好&#xff0c;今天我们来聊一聊sliding window pattern。又是给有个机会给班花讲题的好机会&#xff0c;不能错过&#xff01; Sliding Window Pattern&#xff0c;中文名字叫滑动窗口模式&#xff0c;是一种常见的算法思想。它可以用来解决很多问题&#xff0c;比如&am…

STATA DEA代码说明及样本数据

STATA_DEA代码说明及样本数据 含DEA模型代码和malmquist指数stata代码 包含具体说明 数据包络分析&#xff08;Data envelopment analysis&#xff0c;DEA&#xff09;是运筹学和研究经济生产边界的一种方法。该方法一般被用来测量一些决策部门的生产效率。 DEA是一个线性规…