7.3 C/C++ 实现顺序栈

c++,实现,顺序 · 浏览次数 : 15

小编点评

**顺序栈**是一种基于数组的栈结构,它具有以下特点: * **栈顶元素的下标固定**,而栈底元素的下标随着入栈和出栈操作进行而变化。 * **栈中元素的存储是连续的**,所以访问任意一个元素的时间复杂度为 O(1)。 * **容量有限**,因为它的存储空间是预先分配的,一旦存储空间满了就无法继续入栈,需要重新分配更大的存储空间并将原来的元素复制到新的存储空间中。 **实现**: ```c #include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX 1024typedef void * SeqStack;struct SStack{ void *data[MAX]; // 存放栈元素 int size; // 栈中元素个数};// 初始化一个顺序栈SeqStack InitSeqStack(){ struct SStack *stack = malloc(sizeof(struct SStack)); // 如果stack指针不为空,则将栈初始化一下 if (stack != NULL) { stack->size = 0; for (int i = 0; i < MAX; ++i) { stack->data[i] = NULL; } } return stack; } ``` **使用方法**: ```c PushSeqStack(stack, &stu1); PushSeqStack(stack, &stu2); PushSeqStack(stack, &stu3); ``` **获取栈顶元素**: ```c struct Student *ptr = (struct Student *)TopSeqStack(stack); ``` **释放栈**: ```c DestroySeqStack(stack); ``` **示例**: ```c #include "seqstack.h" struct Student{ int uid; char name[64]; }; int main(int argc, char *argv[]) { SeqStack stack = InitSeqStack(); struct Student stu1 = {1001, "admin"}; struct Student stu2 = {1002, "guest"}; struct Student stu3 = {1003, "lyshark"}; PushSeqStack(stack, &stu1); PushSeqStack(stack, &stu2); PushSeqStack(stack, &stu3); while (SizeSeqStack(stack) > 0) { struct Student *ptr = (struct Student *)TopSeqStack(stack); printf("Uid: %d --> Name: %s \\n", ptr->uid, ptr->name); PopSeqStack(stack); } DestroySeqStack(stack); return 0; } ``` **输出**: ``` Uid: 1001 --> Name: admin Uid: 1002 --> Name: guest Uid: 1003 --> Name: lyshark ```

正文

顺序栈是一种基于数组实现的栈结构,它的数据元素存储在一段连续的内存空间中。在顺序栈中,栈顶元素的下标是固定的,而栈底元素的下标则随着入栈和出栈操作的进行而变化。通常,我们把栈底位置设置在数组空间的起始处,这样在进行入栈和出栈操作时,只需要维护栈顶指针即可。

顺序栈的实现比较简单,它只需要一个数组和一个整型变量top即可。其中,数组用于存储栈中的元素,top则用于记录当前栈顶元素在数组中的位置。当进行入栈操作时,我们将要入栈的元素放在数组的top位置,然后将top加1;当进行出栈操作时,我们先将top减1,然后返回top位置的元素值即可。

顺序栈的优点是实现简单,访问速度快,因为栈中元素的存储是连续的,所以访问任意一个元素的时间复杂度为O(1)。缺点是容量有限,因为它的存储空间是预先分配的,一旦存储空间满了就无法继续入栈,需要重新分配更大的存储空间并将原来的元素复制到新的存储空间中,这样会增加时间和空间的开销。

读者需自行创建头文件seqstack.h并拷贝如下顺序栈代码实现;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 1024
typedef void * SeqStack;

struct SStack
{
    void *data[MAX];   // 存放栈元素
    int size;          // 栈中元素个数
};

// 初始化一个顺序栈
SeqStack InitSeqStack()
{
    struct SStack *stack = malloc(sizeof(struct SStack));
    // 如果stack指针不为空,则将栈初始化一下
    if (stack != NULL)
    {
        stack->size = 0;
        for (int i = 0; i < MAX; ++i)
        {
            stack->data[i] = NULL;
        }
    }
    return stack;
}

// 入栈
void PushSeqStack(SeqStack stack, void *data)
{
    if (stack == NULL || data == NULL)
    {
        return;
    }

    struct SStack *s = (struct SStack *)stack;
    if (s->size == MAX)
    {
        return;
    }

    s->data[s->size] = data;
    s->size++;
}

// 出栈
void PopSeqStack(SeqStack stack)
{
    if (NULL == stack)
    {
        return;
    }

    struct SStack *s = (struct SStack *)stack;

    if (s->size == 0)
    {
        return;
    }

    s->data[s->size - 1] = NULL;
    s->size--;
}

// 获得栈顶元素
void *TopSeqStack(SeqStack stack)
{
    if (NULL == stack)
    {
        return 0;
    }

    struct SStack *s = (struct SStack *)stack;
    if (s->size == 0)
    {
        return 0;
    }

    return s->data[s->size - 1];
}

// 获得栈的大小
int SizeSeqStack(SeqStack stack)
{
    if (NULL == stack)
    {
        return -1;
    }

    struct SStack *s = (struct SStack *)stack;
    return s->size;
}

// 销毁栈
void DestroySeqStack(SeqStack stack)
{
    if (NULL != stack)
    {
        free(stack);
    }
    return;
}

主函数调用如下所示,首先定义一个Student结构体,接着通过使用InitSeqStack函数对栈进程初始化,分别使用PushSeqStack函数向栈中压入不同的参数,最后通过使用循环的方式遍历出栈中的元素,最终调用DestroySeqStack函数销毁栈。

#include "seqstack.h"

struct Student
{
    int uid;
    char name[64];
};

int main(int argc, char *argv[])
{
    // 初始化栈,默认分配空间为1024
    SeqStack stack = InitSeqStack();

    // 穿件一些测试数据
    struct Student stu1 = { 1001, "admin" };
    struct Student stu2 = { 1002, "guest" };
    struct Student stu3 = { 1003, "lyshark" };

    // 将输入加入到栈中
    PushSeqStack(stack, &stu1);
    PushSeqStack(stack, &stu2);
    PushSeqStack(stack, &stu3);

    // 循环输出栈顶元素
    while (SizeSeqStack(stack) > 0)
    {
        // 获得栈顶元素
        struct Student *ptr = (struct Student *)TopSeqStack(stack);
        printf("Uid: %d --> Name: %s \n", ptr->uid, ptr->name);
        printf("当前栈大小: %d \n", SizeSeqStack(stack));
        PopSeqStack(stack);
    }

    // 销毁栈
    DestroySeqStack(stack);
    stack = NULL;

    system("pause");
    return 0;
}

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/7b05e7ce.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

与7.3 C/C++ 实现顺序栈相似的内容:

7.3 C/C++ 实现顺序栈

顺序栈是一种基于数组实现的栈结构,它的数据元素存储在一段连续的内存空间中。在顺序栈中,栈顶元素的下标是固定的,而栈底元素的下标则随着入栈和出栈操作的进行而变化。通常,我们把栈底位置设置在数组空间的起始处,这样在进行入栈和出栈操作时,只需要维护栈顶指针即可。顺序栈的实现比较简单,它只需要一个数组和一个整型变量`top`即可。其中,数组用于存储栈中的元素,top则用于记录当前栈顶元素在数组中的位置。当

[转帖]echo 输出不换行-e \c

http://www.my889.com/i/1952 在shell中,echo输出会自动换行。有时候在循环中不希望echo输出换行。代码实现如下: 1 echo -e " \c" # -e 表示开启转义, \c表示不换行 脚本: 1 2 3 4 5 6 7 8 9 #!/bin/bash i=1

C++多态与虚拟:Objects 实例化(Objects Instantiation)探究

一、Objects的创建 依据已有的class CPoint ,我们可以产生一个或多个object(对象),或者说是产生一个instance(实体): CPoint aPoint(7.2); // aPoint._x 初始值为 7.2 aPoint.x(5.3); // aPoint._x 现值为

源端为备库的场景下Duplicate失败问题

**环境:** Oracle 11.2.0.3 + OEL 7.9 A -> B -> C 级联ADG环境:db11g -> db11gadg -> db11gcas 之前测试提到,从一级备库duplicate到二级备库会报错: ```shell RMAN-00571: RMAN-00569: ER

C++ 初始化列表(Initialization List)

请注意以下继承体系中各class的constructors写法: 1 class CPoint 2 { 3 public: 4 CPoint(float x=0.0) 5 :_x(x){} 6 7 float x() {return _x;} 8 void x(float xval){_x=xval

时间片 线程切换 指令周期 流水线 TPS的初步了解

时间片 线程切换 指令周期 流水线 TPS的初步了解 情况说明 Redis 单线程提供服务, 可以支撑十万级别的TPS 通过以个非常简单的测试 redis-benchmark -c 50 -n 50000 ping Intel 8369HB 3.3Ghz 14万TPS 阿里 倚天710 2.7Ghz

POWERBI_1分钟学会_连续上升或下降指标监控

一:数据源 模拟数据为三款奶茶销量的日销售数据源,日期是23.8.24-23.8.31。A产品为连续7天,日环比下降,B产品为连续3天,日环比下降,C产品为连续2天,日环比下降。 二:建立基础度量值 首先,我们建立两个基础度量值,计算我们的产品销量和日环比。 产品销量 = CALCULATE(SUM

C#集成ViewFaceCore人脸检测识别库

前言 人脸检测与识别现在已经很成熟了,C# 上有 ViewFaceCore 这个很方便的库,但这种涉及到 native 调用的库,一般会有一些坑,本文记录一下开发和部署的过程。 本文的项目是 AIHub ,关于本项目的开发过程,可以参考之前的文章:项目完成小结:使用Blazor和gRPC开发大模型客

7.3 通过API枚举进程

首先实现枚举当前系统中所有进程信息,枚举该进程的核心点在于使用`CreateToolhelp32Snapshot()`函数,该函数用于创建系统进程和线程快照,它可以捕获当前系统中进程和线程相关的信息(如PID、线程数量、线程ID等),在对这些信息进行处理后,可以获得很多有用的数据,如当前系统中所有正在执行的进程的信息列表,以及每个进程各自的详细信息(如CPU、内存占用量等)。

.NET周刊【7月第3期 2023-07-16】

## 国内文章 ### 揭秘 .NET 中的 TimerQueue(上) https://www.cnblogs.com/eventhorizon/p/17557821.html TimerQueue 是.NET中实现定时任务的核心组件,它是一个定时任务的管理器,负责存储和调度定时任务。它被用于实现