首页 > 编程语言 >7.3 C/C++ 实现顺序栈

7.3 C/C++ 实现顺序栈

时间:2023-08-15 09:27:16浏览次数:75  
标签:顺序 return struct C++ 7.3 SStack NULL stack size

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

顺序栈的实现比较简单,它只需要一个数组和一个整型变量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 许可协议。转载请注明出处!

标签:顺序,return,struct,C++,7.3,SStack,NULL,stack,size
From: https://www.cnblogs.com/LyShark/p/17630418.html

相关文章

  • 7.4 C/C++ 实现链表栈
    相对于顺序栈,链表栈的内存使用更加灵活,因为链表栈的内存空间是通过动态分配获得的,它不需要在创建时确定其大小,而是根据需要逐个分配节点。当需要压入一个新的元素时,只需要分配一个新的节点,并将其插入到链表的头部;当需要弹出栈顶元素时,只需要删除链表头部的节点,并释放其所占用的内......
  • 7.5 C/C++ 实现链表队列
    链表队列是一种基于链表实现的队列,相比于顺序队列而言,链表队列不需要预先申请固定大小的内存空间,可以根据需要动态申请和释放内存。在链表队列中,每个节点包含一个数据元素和一个指向下一个节点的指针,头节点表示队头,尾节点表示队尾,入队操作在队尾插入元素,出队操作在队头删除元素,队......
  • C++11时间日期库chrono的使用
    chrono是C++11中新加入的时间日期操作库,可以方便地进行时间日期操作,主要包含了:duration,time_point,clock。时钟与时间点chrono中用time_point模板类表示时间点,其支持基本算术操作;不同时钟clock分别返回其对应类型的时间点。clock时钟是从一个时点开始,按照某个刻度的计数;chrono同......
  • c++20 format基本使用
    下面代码是一个使用format的例子#include<iostream>#include<cmath>#include<format>intmain(){doubleprincipal{1000};doublerate{0.5};std::cout<<std::format("Initialprincipal:{:>7.2f}\n",principal);......
  • C++中的堆
    C++中的堆一、堆的概念堆是一种特殊的树形数据结构,其每个节点都有一个值。通常所说的堆的数据结构,是指二叉堆,即完全二叉树。在C++中,标准库提供了一些用于操作堆的函数,如make_heap(),push_heap(),pop_heap()等。二、堆的特点每个节点的值都大于或等于(最大堆)或小于或等于(最小......
  • C/C++内存管理
    一、C/C++内存分布看下面这段代码:intglobalVar=1;staticintstaticGlobalVar=1;voidTest1(){ staticintstaticVar=1; intlocalVar=1; intnum1[10]={1,2,3,4}; charchar2[]="abcd"; constchar*pChar3="abcd"; int*ptr1=(int*......
  • C/C++内存管理
    一、C/C++内存分布看下面这段代码:intglobalVar=1;staticintstaticGlobalVar=1;voidTest1(){ staticintstaticVar=1; intlocalVar=1; intnum1[10]={1,2,3,4}; charchar2[]="abcd"; constchar*pChar3="abcd"; int*ptr1=(int*......
  • 使用线程实现ACB的顺序输出
    在java中可以使用join方法来实现,join会阻塞当前方法,调用的当前方法执行结束后,才会继续往下执行!publicclassFoo{publicFoo(){}publicvoidA(){System.out.println("A");}publicvoidB(){System.out.println("B");}......
  • c++ std::to_string实现原理
    写这篇的起因是看到MSVCSTL的一个issue,里面提到to_string<int>的实现,正常人的思维是直接除10拿到每位,其实有个更高效的查表法字符串转数字除100拿到两位,并查表填入,少了一半的除法,代价是需要一个201个byte的空间,下面是gcc的实现//Writeanunsignedintegervaluetother......
  • 位运算 学习笔记【C++ 算法竞赛】
    大家好,欢迎来到我的第一篇博客位运算和移位运算作为计算机的基本运算之⼀,其都是对⼆进制位进⾏操作。作为近年算法竞赛笔试较热门的考点,它能够快捷地完成特定的应用。掌握它是⾮常有必要的。以下是目录:目录1.位运算的优先级2.左移运算<<、右移运算>>2.1运算规则:2.2应用:......