栈的实现详解

目录

[一. 栈的概念和结构](#一. 栈的概念和结构)

[二. 栈的实现方式](#二. 栈的实现方式)

1.链表实现栈

[2. 数组实现栈](#2. 数组实现栈)

[三. 栈各个功能实现](#三. 栈各个功能实现)

[1. 结构体的定义](#1. 结构体的定义)

[2. 栈的初始化](#2. 栈的初始化)

[3. 入栈操作](#3. 入栈操作)

[4. 出栈操作](#4. 出栈操作)

[5. 返回栈顶的值](#5. 返回栈顶的值)

[6. 销毁栈](#6. 销毁栈)

[7. 判断栈是否为空](#7. 判断栈是否为空)

[8. 返回栈有多少元素](#8. 返回栈有多少元素)

[四. 完整代码](#四. 完整代码)

[1. stack.h](#1. stack.h)

[2. stack.c](#2. stack.c)

[3. test.c](#3. test.c)


一. 栈的概念和结构

栈是一种特殊的线性表,只允许在固定的一端进行插入和删除元素。进入数据插入和删除操作的一端成为栈顶另一端称为栈底,栈中元素遵守后进先出或先进后出原则

压栈:栈的插入操作叫做(进栈/压栈/入栈)(入数据在栈顶)

出栈:栈的删除操作叫出栈。(出数据在栈顶)

二. 栈的实现方式

栈可以用链表实现也可以用数组实现

1.链表实现栈

如果用尾做栈顶,尾插尾删要设计成双向链表否则插入效率极低

如果用头做栈顶可以设计成单链表的方式

虽然不用扩容但是cpu命中率低

2. 数组实现栈

可以静态实现也可以动态实现

需要扩容,但是cpu命中率高


两种方式各有优劣,这里我们选择使用数组实现

三. 栈各个功能实现

1. 结构体的定义
cpp 复制代码
typedef int StackType;
typedef struct Stack
{
	StackType* a;//StackType是存储元素的类型
	int Top;
	int capacity;
}ST,*pS;

三个参数的含义:

a:指针,用来存储数据

Top:栈顶元素在a中的位置

capacity:a能容纳的元素个数

2. 栈的初始化
cpp 复制代码
void StackInit(pS pst)
{
	assert(pst);
	
	pst->a = NULL;
	pst->capacity = 0;
	pst->Top = 0;
}

此处pst->Top可以初始化为0也可以初始化为-1,代表栈顶元素在a中的位置或者代表栈顶元素在a中位置的下一个(两种写法对后面代码会产生影响)

3. 入栈操作
cpp 复制代码
void BuyNode(pS pst)
{

	int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
	StackType* tmp = (StackType*)realloc(pst->a, sizeof(StackType) * newcapacity );
	if (tmp == NULL)
	{
		perror("relloc fail");
		return;
	}
	pst->a = tmp;
	pst->capacity = newcapacity;
}

void StackPush(pS pst, StackType data)
{
	assert(pst);
	if (pst->Top == pst->capacity)
	{
		BuyNode(pst);
	}
	pst->a[pst->Top] = data;
	pst->Top++;
}

扩容时要看是容量(capacity)是0还是非0,非0就扩充2倍,0就赋值为4来开辟动态内存

如果上文Top初始化为-1,此处的pst->Top++要在赋值前

4. 出栈操作
cpp 复制代码
void StackPop(pS pst)
{
	assert(pst);

	pst->Top--;//数组里的值不用改,再添加数据会覆盖掉
}
5. 返回栈顶的值
cpp 复制代码
StackType StackTop(pS pst)
{
	assert(pst);

	return pst->a[pst->Top-1];
}

因为Top指向的是栈顶元素的下一个位置,所以要-1

6. 销毁栈
cpp 复制代码
void StackDestroy(pS pst)
{
	assert(pst);
	
	free(pst->a);
	pst->a = NULL;
	pst->capacity = 0;
	pst->Top = 0;
}
7. 判断栈是否为空
cpp 复制代码
bool StackEmpty(pS pst)
{
	assert(pst);
	return pst->Top == 0; 
}
8. 返回栈有多少元素
cpp 复制代码
int StackSize(pS pst)
{
	assert(pst);

	return pst->Top;
}

数组存储是有0这个下标的,所以直接返回Top,如果Top是指向栈顶元素那返回Top+1

四. 完整代码

1. stack.h
cpp 复制代码
#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
#include<stdlib.h>
typedef int StackType;

typedef struct Stack
{
	StackType* a;
	int Top;
	int capacity;
}ST,*pS;
//初始化
void StackInit(pS pst);
//入栈
void StackPush(pS pst,StackType data);
//出栈
void StackPop(pS pst);
//取栈顶数据
StackType StackTop(pS pst);
//判空
bool StackEmpty(pS pst);
//获取数据个数
int StackSize(pS pst);

void StackDestroy(pS pst);
2. stack.c
cpp 复制代码
#include"stack.h"

//初始化
void StackInit(pS pst)
{
	assert(pst);
	
	pst->a = NULL;
	pst->capacity = 0;
	pst->Top = 0;
}

void BuyNode(pS pst)
{

	int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
	StackType* tmp = (StackType*)realloc(pst->a, sizeof(StackType) * newcapacity );
	if (tmp == NULL)
	{
		perror("relloc fail");
		return;
	}
	pst->a = tmp;
	pst->capacity = newcapacity;
}

void StackPush(pS pst, StackType data)
{
	assert(pst);
	if (pst->Top == pst->capacity)
	{
		BuyNode(pst);
	}
	pst->a[pst->Top] = data;
	pst->Top++;
}

void StackPop(pS pst)
{
	assert(pst);

	pst->Top--;//数组里的值不用改,再添加数据会覆盖掉
}

StackType StackTop(pS pst)
{
	assert(pst);

	return pst->a[pst->Top-1];
}

void StackDestroy(pS pst)
{
	assert(pst);
	
	free(pst->a);
	pst->a = NULL;
	pst->capacity = 0;
	pst->Top = 0;
}
bool StackEmpty(pS pst)
{
	assert(pst);
	return pst->Top == 0; 
}

int StackSize(pS pst)
{
	assert(pst);

	return pst->Top;
}
3. test.c
cpp 复制代码
#include"stack.h"


int main()
{
	ST s = { 0 };
	StackInit(&s);
	StackPush(&s, 2);
	StackPush(&s, 2);
	StackPush(&s, 3);
	StackPush(&s, 3);
	printf("%d\n", StackSize(&s));
	while(!StackEmpty(&s))
	{
		printf("%d\n", StackTop(&s));
		StackPop(&s);
	}
	StackDestroy(&s);
	return 0;
}

本篇文章到此结束希望可以帮到您(๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤

(づ ̄3 ̄)づ╭❤~ 再见啦~

相关推荐
郭二哈2 分钟前
C++——list
开发语言·c++·list
杨荧3 分钟前
【JAVA开源】基于Vue和SpringBoot的洗衣店订单管理系统
java·开发语言·vue.js·spring boot·spring cloud·开源
ZPC821010 分钟前
Python使用matplotlib绘制图形大全(曲线图、条形图、饼图等)
开发语言·python·matplotlib
镜花照无眠11 分钟前
Python爬虫使用实例-mdrama
开发语言·爬虫·python
sp_fyf_202413 分钟前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-03
人工智能·算法·机器学习·计算机视觉·语言模型·自然语言处理
aaasssdddd9622 分钟前
python和c
c语言·开发语言·python
星星法术嗲人36 分钟前
【Java】—— 集合框架:Collections工具类的使用
java·开发语言
Ljubim.te41 分钟前
软件设计师——数据结构
数据结构·笔记
Eric.Lee20211 小时前
数据集-目标检测系列- 螃蟹 检测数据集 crab >> DataBall
python·深度学习·算法·目标检测·计算机视觉·数据集·螃蟹检测
黑不溜秋的1 小时前
C++ 语言特性29 - 协程介绍
开发语言·c++