本文主要使用数组实现一种特殊的线性表-栈
文章目录
前言
什们叫做栈
- 栈的概念
- 一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
- 一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
- 栈的功能
- 只允许栈顶,出去和进来元素,栈底不允许进来和出去元素,所以符合先进后出,后进先出
栈的实现
- 用什么实现栈
- 栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
也就是我们的顺序表,我们顺序表的尾插实现和尾删简单,但是头插复杂。
为什们我们不用链表呢?因为我们单链表的尾插还得找尾才能插入呢,有点复杂所以不用。但是单链表的头插简单,我们可以利用头插,也就是让头充当栈顶,来进行插入删除。
所以顺序表和链表都是可以的,大家按照需求自己选择,我们利用顺序表,也就是数组实现栈。
- 栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
1、创建文件
首先建立三个文件
Stack.h
:用来编写栈的头文件。
Stack.c
:用来编写栈的函数
test.c
:测试栈的功能。
2、创建栈的结构体
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int capacity;
int top;
}Stack;
2、栈的初始化
//初始化栈
//这样也可以,但是后序尾插还要给他空间
//void StackInit(Stack* ps)
//{
// assert(ps);
// ps->a = NULL;
// ps->capacity = 0;
// ps->top = 0;
//}
//初始化栈-直接给4个空间
void StackInit(Stack* ps)
{
assert(ps);
STDataType* temp = (STDataType*)malloc(sizeof(STDataType) * 4); //初始化4个空间
if (temp == NULL)
{
perror("malloc fail");
exit(-1);
}
ps->a = temp;
ps->capacity = 4;
ps->top = -1; //因为如果是0的话,先插入再++,此时top九七不指向栈顶了
}
3、栈的销毁
//栈的销毁
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
4、栈顶插入
top初始为0,指向栈顶的下一个元素
top初始为-1,指向栈顶元素
//栈的尾插
void StackPushBack(Stack* ps, STDataType x)
{
assert(ps);
if (ps->capacity == ps->top)
{
int newcapacity = ps->capacity * 2;
STDataType* temp = (STDataType*)malloc(sizeof(newcapacity));
if (temp == NULL)
{
perror("malloc fail");
exit(-1);
}
ps->a = temp;
ps->capacity = newcapacity;
}
ps->a[++(ps->top)] = x; //先++再插入
}
如果top和capacity都初始化为0,则尾插函数就是这样
5、栈顶判空
//栈的判空
bool StackEmpty(Stack* ps)
{
return ps->top == -1; //因为初始化就是-1
}
6、栈顶删除
//栈的尾删
void StackPopBack(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
7、取栈顶元素
//取栈顶元素
int StackTop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top];
}
8、计算栈元素个数
//栈的元素个数
int StackSize(Stack* ps)
{
assert(ps);
return ps->top + 1;
}
程序源码
stack.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int capacity;
int top;
}Stack;
//初始化栈
void StackInit(Stack* ps);
//栈的销毁
void StackDestroy(Stack* ps);
//栈的尾插
void StackPushBack(Stack* ps, STDataType x);
//栈的尾删
void StackPopBack(Stack* ps);
//栈的判空
bool StackEmpty(Stack* ps);
//取栈顶元素
int StackTop(Stack* ps);
//栈的元素个数
int StackSize(Stack* ps);
stack.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "stack.h"
//初始化栈-直接给4个空间
void StackInit(Stack* ps)
{
assert(ps);
STDataType* temp = (STDataType*)malloc(sizeof(STDataType) * 4); //初始化4个空间
if (temp == NULL)
{
perror("malloc fail");
exit(-1);
}
ps->a = temp;
ps->capacity = 4;
ps->top = -1; //因为如果是0的话,先插入再++,此时top九七不指向栈顶了
}
//栈的销毁
void StackDestroy(Stack* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
//初始化栈
//这样也可以,但是后序尾插还要给他空间
//void StackInit(Stack* ps)
//{
// assert(ps);
// ps->a = NULL;
// ps->capacity = 0;
// ps->top = 0;
//}
栈的尾插
//void StackPushBack(Stack* ps, STDataType x)
//{
// assert(ps);
// if (ps->capacity == ps->top)
// {
// int newcapacity = ps->capacity == 0 : 4 ? ps->capacity;
// STDataType* temp = (STDataType*)malloc(sizeof(newcapacity));
// if (temp == NULL)
// {
// perror("malloc fail");
// exit(-1);
// }
// ps->a = temp;
// ps->capacity = newcapacity;
// }
// ps->a[++(ps->top)] = x; //先++再插入
//}
//栈的尾插
void StackPushBack(Stack* ps, STDataType x)
{
assert(ps);
if (ps->capacity == ps->top)
{
int newcapacity = ps->capacity * 2;
STDataType* temp = (STDataType*)malloc(sizeof(newcapacity));
if (temp == NULL)
{
perror("malloc fail");
exit(-1);
}
ps->a = temp;
ps->capacity = newcapacity;
}
ps->a[++(ps->top)] = x; //先++再插入
}
//栈的判空
bool StackEmpty(Stack* ps)
{
return ps->top == -1; //因为初始化就是-1
}
//栈的尾删
void StackPopBack(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
//取栈顶元素
int StackTop(Stack* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top];
}
//栈的元素个数
int StackSize(Stack* ps)
{
assert(ps);
return ps->top + 1;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "stack.h"
void test()
{
Stack st;
StackInit(&st);
StackPushBack(&st, 1);
StackPushBack(&st, 2);
StackPushBack(&st, 3);
printf("top1=%d\n", StackTop(&st));
printf("size=%d\n", StackSize(&st));
StackPopBack(&st);
printf("top2=%d\n", StackTop(&st));
printf("size=%d\n", StackSize(&st));
StackPopBack(&st);
printf("top3=%d\n", StackTop(&st));
printf("size=%d\n", StackSize(&st));
StackDestroy(&st);
}
int main()
{
test();
return 0;
}