1.前言
无论是顺序栈和链表栈,栈都是后进先出,a1最先进入栈却最后出栈。
只不过顺序栈是用数组实现的,而链表栈是用链表实现的。
顺序栈要先确定开辟的堆的大小,而链表栈是用多少开辟多少。
2.顺序栈代码组成
2.1 SeqStack.h,定义顺序栈的功能
#pragma once
#define MAX_SIZE 1024
//数组模拟栈的顺序存储
typedef struct SEQSTACK
{
void* data[MAX_SIZE];
int size;
}SeqStack;
//初始化栈
SeqStack* Init_SeqStack();
//入栈
void Push_SeqStack(SeqStack* stack, void* data);
//返回栈顶元素
void* Top_SeqStack(SeqStack* stack);
//出栈
void Pop_SeqStack(SeqStack* stack);
//判断栈是否为空
int IsEmpty(SeqStack* stack);
//返回栈中的元素个数
int Size_SeqStack(SeqStack* stack);
//清空栈
void Clear_SeqStack(SeqStack* stack);
//销毁栈
void FreeSpace_SeqStack(SeqStack* stack);
如前言所说,指定了MAX_SIZE为1024,也就是前言中的图可以理解为a1-a1024
2.2 SeqStack.cpp 顺序栈的函数的具体实现代码
#include"SeqStack.h"
#include<iostream>
//初始化栈
SeqStack* Init_SeqStack()
{
SeqStack* stack = new SeqStack;
for (int i = 0; i < MAX_SIZE; i++)
{
stack->data[i] = NULL;
}
stack->size = 0;
return stack;
}
//入栈
void Push_SeqStack(SeqStack* stack, void* data)
{
if (stack == NULL)return;
if (stack->size == MAX_SIZE)return;
if (data == NULL)return;
stack->data[stack->size] = data;
stack->size++;
}
//返回栈顶元素
void* Top_SeqStack(SeqStack* stack)
{
if (stack == NULL)return NULL;
if (stack->size == 0)return NULL;
return stack->data[stack->size - 1];
}
//出栈
void Pop_SeqStack(SeqStack* stack)
{
if (stack == NULL)return ;
if (stack->size == 0)return;
stack->data[stack->size - 1] = NULL;
stack->size--;
}
//判断栈是否为空
int IsEmpty(SeqStack* stack)
{
if (stack == NULL)return -1;
if (stack->size == 0)return 1;
return 0;
}
//返回栈中的元素个数
int Size_SeqStack(SeqStack* stack)
{
return stack->size;
}
//清空栈
void Clear_SeqStack(SeqStack* stack)
{
if (stack == NULL)return;
for (int i = 0; i < stack->size; i++) {
stack->data[i] = NULL;
}
stack->size = 0;
}
//销毁栈
void FreeSpace_SeqStack(SeqStack* stack)
{
if (stack == NULL)return;
delete stack;
}
2.2.1 初始化顺序栈SeqStack* Init_SeqStack()
开辟栈,从0-1023(下标是从0开始的)循环将数据设置为NULL,将顺序栈的大小设置为0完成,初始化
2.2.2 入栈void Push_SeqStack(SeqStack* stack, void* data)
stack->data[stack->size] = data;注意里面用的是stack->size
2.2.3返回栈顶元素void* Top_SeqStack(SeqStack* stack)
return stack->data[stack->size - 1];
stack->size - 1的原因:因为栈的下标从0开始。例如我有1024个数据放进栈,栈的size是1024,但是栈的下边是从0-1023
2.2.4 出栈void Pop_SeqStack(SeqStack* stack)
stack->data[stack->size - 1] = NULL;从顶端开始出栈,别忘记size减1
2.2.5 判空int IsEmpty(SeqStack* stack)
2.2.6 返回栈的元素格式int Size_SeqStack(SeqStack* stack)
2.2.7 清空栈void Clear_SeqStack(SeqStack* stack)
这里用了一个循环将栈的data设置为NULL,最后将栈的size设置为0
2.2.8 销毁栈void FreeSpace_SeqStack(SeqStack* stack)
2.3 test.cpp 测试顺序栈
#include"SeqStack.h"
#include<iostream>
typedef struct PERSON {
char name[64];
int age;
}Person;
void test_SeqStack()
{
SeqStack* stack = Init_SeqStack();
Person p1 = { "aaa",10 };
Person p2 = { "bbb",20 };
Person p3 = { "ccc",30 };
Person p4 = { "ddd",40 };
Person p5 = { "eee",50 };
Push_SeqStack(stack, &p1);
Push_SeqStack(stack, &p2);
Push_SeqStack(stack, &p3);
Push_SeqStack(stack, &p4);
Push_SeqStack(stack, &p5);
//输出
while (Size_SeqStack(stack)>0)
{
//访问栈顶元素
Person* person=(Person*)Top_SeqStack(stack);
std::cout << "姓名: " << person->name << " 年龄: " << person->age << std::endl;
//出栈
Pop_SeqStack(stack);
}
FreeSpace_SeqStack(stack);
}
int main()
{
test_SeqQueue();
return 0;
}
首先创建栈,然后用初始化函数进行初始化,接着入栈,然后用Size函数判断栈是否为空,不为空就循环输出,最后释放栈
2.4 顺序栈运行结果![](https://img-blog.csdnimg.cn/direct/36b5733f798c461c981fe2326968a2f0.png)
可以从结果看到是先入后出
3.链表栈代码组成
这里就不过多叙述了,思想和顺序栈一样
3.1 LinkStack.h(这里采用的是企业链表的思想,找一找我前几天的博客)
#pragma once
typedef struct LINKNODE {
struct LINKNODE* next;
}LinkNode;
typedef struct LINKSTACK {
LinkNode head;
int size;
}LinkStack;
//初始化函数
LinkStack* Init_LinkStack();
//入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data);
//出栈
void Pop_LinkStack(LinkStack* stack);
//返回栈顶元素
LinkNode* Top_LinkStack(LinkStack* stack);
//返回栈元素的个数
int Size_LinkStack(LinkStack* stack);
//清空栈
void Clear_LinkStack(LinkStack* stack);
//销毁栈
void FreeSpace_LinkStack(LinkStack* stack);
3.2 LinkStack.cpp
#include"LinkStack.h"
//初始化函数
LinkStack* Init_LinkStack()
{
LinkStack* stack = new LinkStack;
stack->head.next = nullptr;
stack->size = 0;
return stack;
}
//入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data)
{
if (stack == nullptr)return;
if (data == nullptr)return;
data->next = stack->head.next;
stack->head.next = data;
stack->size++;
}
//出栈
void Pop_LinkStack(LinkStack* stack)
{
if (stack == nullptr)return;
if (stack->size == 0)return;
//第一个有效节点
LinkNode* pNext = stack->head.next;
stack->head.next = pNext->next;
stack->size--;
}
//返回栈顶元素
LinkNode* Top_LinkStack(LinkStack* stack)
{
if (stack == nullptr)return nullptr;
if (stack->size == 0)return nullptr;
return stack->head.next;
}
//返回栈元素的个数
int Size_LinkStack(LinkStack* stack)
{
if (stack == nullptr)return -1;
return stack->size;
}
//清空栈
void Clear_LinkStack(LinkStack* stack)
{
if (stack == nullptr)return;
stack->head.next = nullptr;
stack->size = 0;
}
//销毁栈
void FreeSpace_LinkStack(LinkStack* stack)
{
if (stack == nullptr)return;
delete stack;
}
3.3 test.cpp
#include"LinkStack.h"
#include<iostream>
typedef struct PERSON_LINKSTACK {
LinkNode node;
char name[64];
int age;
}Person_LinkStack;
void test_LinkStack()
{
//创建栈
LinkStack* stack = Init_LinkStack();
//创建数据
Person_LinkStack p1, p2, p3, p4, p5;
strcpy_s(p1.name,"aaa");
strcpy_s(p2.name, "bbb");
strcpy_s(p3.name, "ccc");
strcpy_s(p4.name, "ddd");
strcpy_s(p5.name, "eee");
p1.age = 10;
p2.age = 20;
p3.age = 30;
p4.age = 40;
p5.age = 50;
//入栈
Push_LinkStack(stack, (LinkNode*)&p1);
Push_LinkStack(stack, (LinkNode*)&p2);
Push_LinkStack(stack, (LinkNode*)&p3);
Push_LinkStack(stack, (LinkNode*)&p4);
Push_LinkStack(stack, (LinkNode*)&p5);
//输出
while (Size_LinkStack(stack)>0)
{
//访问栈顶元素
Person_LinkStack* person=(Person_LinkStack*)Top_LinkStack(stack);
std::cout << "姓名: " << person->name << " 年龄: " << person->age << std::endl;
//出栈
Pop_LinkStack(stack);
}
//销毁栈
FreeSpace_LinkStack(stack);
}
int main()
{
test_LinkStack();
return 0;
}
因为结构体中用的是char [64],strcpy函数我用了会有安全问题的报错,采用strcpy_s函数即可