[全网最细数据结构完整版]第六篇:3分钟带你吃透栈并模拟实现

news/2024/11/8 18:33:41 标签: c语言, c++, 开发语言, 算法, 数据结构, java, 游戏

目录

1->栈的概念和结构

1.1栈的概念

 1.2栈的结构

 2->栈的实现

2.1定义关于栈的结构体和各种函数

2.2栈的初始化 STInit 函数

2.3栈的销毁 STDestroy 函数

2.4栈的插入操作 STPush 函数 

2.5栈的判断是否为空操作 STEmpty 函数 

2.6栈的删除操作 STPop 函数

2.7栈的取栈顶元素操作 STTop 函数

2.8求栈的大小即有效元素的个数 STSize 函数

3->测试下我们自己写的栈

4->您的专属鼓励师


1->栈的概念和结构

1.1栈的概念

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

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

出栈:栈的删除操作叫做出栈。出数据也在栈顶

 1.2栈的结构

 

 2->栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小.

使用数组模拟原理:

 使用链表模拟原理:

 

// 下面是定长的静态栈的结构,实际中一般不实用,所以我们主要实现下面的支持动态增长的栈
typedef int STDataType;
#define N 10
typedef struct Stack
{
    STDataType _a[N];
    int _top; // 栈顶
}Stack;

2.1定义关于栈的结构体和各种函数

#pragma once
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>


typedef struct Stack
{
	int* _arr;//开辟在堆区上存储数据的数组
	int _top;//栈顶的下一个位置
	int _capacity;//栈的容量
}ST;



//1.栈初始化
void STInit(ST* pst);
//2.栈的销毁
void STDestroy(ST* pst);
//3.栈的插入操作
void STPush(ST* pst, int x);
//4.栈的删除操作
void STPop(ST* pst);
//5.取栈顶元素
int STTop(ST* pst);
//6.判断栈是否为空,空为true,非空为false
bool STEmpty(ST* pst);
//7.求栈的大小即有效元素的个数
int STSize(ST* pst);

2.2栈的初始化 STInit 函数

//1.栈初始化
void STInit(ST* pst)
{
	assert(pst);
	pst->_arr = NULL;
	pst->_capacity = 0;
	pst->_top = 0;//指向栈顶元素的下一个位置,类似于
				  //之前写的顺序表中的_size,指向未使用位置
}

2.3栈的销毁 STDestroy 函数

//2.栈的销毁
void STDestroy(ST* pst)
{
	assert(pst);

	free(pst->_arr);//清理位于堆上的数组
	pst->_arr = NULL;
	pst->_capacity = pst->_top = 0;
}

2.4栈的插入操作 STPush 函数 

//3.栈的插入操作
void STPush(ST* pst, int x)
{
	assert(pst);
	//插入数据之前判断一下容量是否足够,不够就扩容
	if (pst->_top == pst->_capacity)//容量满了,扩容
	{
		//刚开始插入给4个空间,否则就2倍扩容
		int newcapacity = (pst->_capacity == 0 ? 4 : pst->_capacity * 2);

		int* newarr = (int*)realloc(pst->_arr, newcapacity * sizeof(int));
		if (newarr == NULL)
		{
			perror("realloc failed");
			return;
		}
		pst->_arr = newarr;
		pst->_capacity = newcapacity;
	}
	//有容量了,插入数据
	pst->_arr[pst->_top] = x;
	pst->_top++;
}

2.5栈的判断是否为空操作 STEmpty 函数 

//4.判断栈是否为空,空为true,非空为false
bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->_top == 0;
}

2.6栈的删除操作 STPop 函数

//5.栈的删除操作
void STPop(ST* pst)
{
	//首先你得有元素才能删除对吧
	assert(pst);
	assert(!STEmpty(pst));

	pst->_top--;
}

2.7栈的取栈顶元素操作 STTop 函数

//6.取栈顶元素
int STTop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));

	return pst->_arr[pst->_top - 1];
}

2.8求栈的大小即有效元素的个数 STSize 函数

//7.求栈的大小即有效元素的个数
int STSize(ST* pst)
{
	assert(pst);
	return pst->_top;
}

3->测试下我们自己写的栈

#include "Stack.h"



//1.测试栈插入,删除,取栈顶元素
void testStack1()
{
	ST st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
	STPush(&st, 5);

	while (!STEmpty(&st))
	{
		printf("%d : ",STTop(&st));
		STPop(&st);
	}
	STDestroy(&st);

}




int main()
{
	testStack1();
	return 0;
}

运行,看控制台输出:欧耶,我们自己写的栈可以正常运行

4->您的专属鼓励师

        有些事情,你永远都没有办法做到“顶尖”,因为智力跟不上.但是所有的事情,你都可以做到“高段”,因为它需要的是时间的累积和精力的打磨.不聪明与聪明之间的区别,是很微妙的.有时候我们只会通过一次两次的结果,来判断整个人、整件事,其实这是不明智的.从小,邻居和亲戚在谈论我的时候,都会觉得我很聪明。但是只有我自己知道,我从来没有聪明过,只是看上去比较聪明而已.

        修行之路确实枯燥,但是我们把问题搞懂以后就发现他是那样的美妙!一遍学不会没关系吖,多看几遍,我也是学了好多遍呢,小伙伴们肯定学的又快又好!!!最后希望写的内容对小伙伴们有所帮助,我写的如果有哪里不对的地方请在评论区或者私信指出来哦!让我们一起进步吖,任何疑问包括心情不好都可以找我聊聊,我很乐意当你的倾听者吖.   


http://www.niftyadmin.cn/n/5744291.html

相关文章

vue2组件封装和UI组件的二次封装,方法,属性,ref的传递

封装组件使用v-model 使用方法props接受value值&#xff0c;当值发生变化的时候再通过this.$emit("input", newValue)&#xff0c;则实现了简单组件的v-model封装,如果不使用第三方UI可以接受到的值使用watch或者计算属性保存&#xff0c;然后再通过事件派发自己保存…

AI 重塑软件开发:流程、优势、挑战与应对

一、流程与模式介绍【传统软件开发 VS AI 参与的软件开发】 传统软件开发流程与模式 传统的软件开发是一个复杂且严谨的过程&#xff0c;通常遵循一系列既定的步骤。 需求分析&#xff1a; 开发团队与客户或相关利益者紧密合作&#xff0c;详细了解软件需要实现的功能、性能要…

面粉直供系统|基于java和小程序的食品面粉直供系统设计与实现(源码+数据库+文档)

面粉直供系统 目录 基于java和小程序的食品面粉直供系统设计与实现 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师&#x…

Docker Compose V2 安装

要安装 docker-compose-plugin&#xff0c;需要确保系统已安装 Docker 引擎&#xff0c;因为 docker-compose-plugin 是 Docker CLI 的插件&#xff08;Docker Compose V2&#xff09;。以下是详细指南&#xff1a; 1. 安装 Docker 引擎&#xff1a; 确保系统上安装了 Docker…

梧桐数据库聚合函数使用举例

在数据分析和数据库管理中&#xff0c;聚合函数是一类非常重要的工具&#xff0c;它们能够对数据集进行计算并返回单个结果。梧桐数据库提供了丰富的聚合函数&#xff0c;这些函数可以帮助我们快速地对数据进行汇总、分析和处理。本文将介绍梧桐数据库中一些常用的聚合函数及其…

数据中异常值的鉴定和处理(1)

数据预处理中最不想碰到但又绕不过的一个问题是异常样品的鉴定和处理。异常样本&#xff0c;也称为离群样本&#xff0c;其定义是与其它样本有显着差异的样本。通常是由实验操作失败、样本受损等不易发现的外部因素引起&#xff0c;比如样本被污染了、细胞死亡了、细胞破损了、…

机器学习与深度学习-1-线性回归从零开始实现

机器学习与深度学习-1-线性回归从零开始实现 1 前言 ​ 内容来源于沐神的《动手学习深度学习》课程&#xff0c;本篇博客对线性回归从零开始实现&#xff08;即不调用封装好的库&#xff0c;如SGD优化器、MSE损失函数等&#xff09;进行重述&#xff0c;并且修改了沐神的课堂…

【bug日志-水】解决本地开发下代理和url同名导致刷新404的问题

bug描述 在本地开发&#xff0c;并且路由是history的模式下&#xff0c;代理和url同名的情况下&#xff0c;刷新会404。 {path: /googleAds,//如果有个代理也叫googleAds&#xff0c;刷新时就会404name: googleAds,icon: sound,routes: [{path: /googleAds/GoogleAdsSettingPag…