7.3 C/C++ 实现顺序栈

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

顺序栈的实现比较简单,它只需要一个数组和一个整型变量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;
}