栈 :只能在表尾进行插入(入栈)和删除(出栈)的数据结构(受到限制的线性表)
表尾比较特殊,我们一般把这个表尾叫做栈顶,另一端栈底,没有数据节点,则叫做空栈。
特点:后进先出 (LIFO),先进后出
顺序栈结构体设计:
struct Stack
{
第一个数据成员:ELEM_TYPE *base(指针类型,接收malloc从堆里申请的一整块连续的空间)
第二个数据成员: int top (用一个变量表示下一个数据的插入位置,也能表示有效值个数)
第三个数据 成员:int stack_size (存储当前容量大小)
};
程序实现:
Stack.h
#pragma once
//顺序栈的结构体设计:
#define INIT_SIZE 10
typedef int ELEM_TYPE;
typedef struct Stack
{
ELEM_TYPE* base;//一个指针,用来接收malloc从堆内申请的一整块内存
int top;//栈顶指针(和书上不一致,书上是指针类型,我们这里存的是数组下标,所以用int类型,也能达到指针的作用)
int stack_size;//存储当前的最大容量
}Stack, * PStack;
//顺序栈可执行函数的声明
//初始化
void Init_Stack(struct Stack* ps);
//入栈(插入)
bool Push(PStack ps, ELEM_TYPE val);
//出栈(获取删除的栈顶元素值,并且删除) //用到一个输出参数
bool Pop(PStack ps, ELEM_TYPE* rtval);
//获取栈顶元素(获取栈顶元素值,但是不删除) //用到一个输出参数
bool Top(PStack ps, ELEM_TYPE* rtval);
//判空
bool IsEmpty(PStack ps);
//判满
bool IsFull(PStack ps);
//扩容
void Inc(PStack ps);
//获取有效长度
int Get_length(PStack ps);
//清空
void Clear(PStack ps);
//销毁
void Destroy(PStack ps);
//打印
void Show(PStack ps);
Stack.cpp
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include "Stack.h"
//顺序栈可执行函数的声明
//初始化
void Init_Stack(struct Stack* ps)
{
//assert
ps->base = (ELEM_TYPE*)malloc(INIT_SIZE * sizeof(struct Stack));
assert(ps->base != NULL);
ps->top = 0;
ps->stack_size = INIT_SIZE;
}
//入栈(插入)
bool Push(PStack ps, ELEM_TYPE val)
{
assert(ps != NULL);
if (ps == NULL)
{
return false;
}
//入栈需要判满
if (IsFull(ps))
{
Inc(ps);
}
执行到这一行 总会有额外空间去入栈
//ps->base[ps->top] = val;
warning: 插入或删除结束后,记得挪动一下栈顶指针top
//ps->top++;
ps->base[ps->top++] = val;
return true;
}
//出栈(获取删除的栈顶元素值,并且删除) //用到一个输出参数
bool Pop(PStack ps, ELEM_TYPE* rtval)
{
assert(ps != NULL);
if (ps == NULL)
{
return false;
}
//出栈需要判空
if (IsEmpty(ps))
{
return false;
}
/*ps->top--;
*rtval = ps->base[ps->top];*/
*rtval = ps->base[--ps->top];
return true;
}
//获取栈顶元素(获取栈顶元素值,但是不删除) //用到一个输出参数
bool Top(PStack ps, ELEM_TYPE* rtval)
{
assert(ps != NULL);
if (ps == NULL)
{
return false;
}
if (IsEmpty(ps))
{
return false;
}
*rtval = ps->base[ps->top - 1];
return true;
}
//判空
bool IsEmpty(PStack ps)
{
return ps->top == 0;
}
//判满
bool IsFull(PStack ps)
{
return ps->top == ps->stack_size;
}
//扩容 按2倍扩容
static void Inc(PStack ps)
{
assert(ps != NULL);
if (ps == NULL)
{
return ;
}
//当realloc前面参数为0 相当于malloc 当后边参数为0 相当于free
ps->base = (ELEM_TYPE*)realloc(ps->base, ps->stack_size * sizeof(struct Stack) * 2);
assert(ps->base != NULL);
ps->stack_size *= 2;
//ps->top; 这个变量不需要处理
}
//获取有效长度
int Get_length(PStack ps)
{
assert(ps != NULL);
if (ps == NULL)
{
return false;
}
return ps->top;
}
//清空 //不需要释放malloc申请的空间 只需要将栈顶指针改为0 则认为里面数据都失效(没有有效债)
void Clear(PStack ps)
{
ps->top = 0;
}
//销毁 //需要释放malloc申请的空间
void Destroy(PStack ps)
{
assert(ps != NULL);
if (ps == NULL)
{
return ;
}
free(ps->base);
ps->base = NULL;
ps->stack_size = ps->top = 0;
}
//打印
void Show(PStack ps)
{
for (int i = 0; i < ps->top; i++)
{
printf("%d ", ps->base[i]);
}
printf("\n");
}
测试:
#include<stdio.h>
#include<assert.h>
#include<malloc.h>
#include"Stack.h"
int main()
{
struct Stack head;
Init_Stack(&head);
for (int i = 0; i < 10; i++)
{
Push(&head, i);
}
Show(&head);
return 0;
}
首先在表里面插入数据:
删除栈顶数据: