简单的数据结构:栈

news2024/11/19 10:28:41

1.栈的基本概念

1.1栈的定义

栈是一种线性表,只能在一端进行数据的插入或删除,可以用数组链表来实现,这里以数组为例进行说明

栈顶 :数据出入的那一端,通常用Top表示

栈底 :相对于栈顶的另一端,也是固定的一端,不允许数据的插入和删除

空栈:不含数据的栈

1.2栈的基本操作

栈的初始化:通常用STInit(&St)表示,用来初始化一个栈St

入栈:一般用STPush(&St, x)表示,给栈St插入数据x,也叫做进栈压栈,同时要注意是否栈满,栈满则需要扩容

出栈:一般用STPop(&St)表示,给栈St删除数据,有时也叫弹栈,需要注意是否栈空

 判断栈空:用STEmpty(&St)表示,常用到判断栈空,因此封装成函数,方便使用,返回值一般用bool类型,true表示栈空,false表示栈非空 

 读栈顶元素:用STTop(&St)表示,栈非空则返回栈顶元素

获取数据个数:用STSize(&St)表示 ,返回数据个数

2.栈的实现 

用一个结构体描述这个栈的各项数据:

typedef int STDataType;

typedef struct Stack
{
    STDataType* a;   //栈底
    int top;                 //栈顶
    int capacity;         //栈容量
}ST;

初始化栈: 

void STInit(ST* pst)
{
    assert(pst);
    pst->a = NULL;
    //top指向栈顶数据的下一个位置
    pst->top = 0;
    pst->capacity = 0;
}

top可以指向栈顶,也可以指向栈顶的下一个位置,top的指向会影响后续的数据插入、删除、销毁,以及判空 

 栈的销毁:

void STDestroy(ST* pst)
{
    assert(pst);

    free(pst->a);
    pst->a = NULL;
    pst->capacity = 0;
    pst->top = 0;
}

 入栈:

void STPush(ST* pst, STDataType x)
{
    assert(pst);

    //扩容
    if (pst->top == pst->capacity)
    {
        int    newcapacity = pst->capacity == 0 ? 4 : pst->capacity* 2; //空栈则让栈空间为4
        STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
        if (tmp == NULL)
        {
            perror("realloc fail");    
            return;
        }

        pst->a = tmp;
        pst->capacity = newcapacity;
    }
    pst->a[pst->top] = x;
    pst->top++;
}
 

利用realloc的特性,空栈则执行malloc的功能 

出栈:

void STPop(ST* pst)
{
    assert(pst);
    assert(pst->top > 0);   //防止栈空
    pst->top--;
}

 取栈顶数据:

STDataType STTop(ST* pst)
{
    assert(pst);
    return pst->a[pst->top - 1];  //返回值为STDataType
}

判空:

bool STEmpty(ST* pst)
{
    assert(pst);
    return pst->top == 0;
}

获取栈的数据个数:

int    STSize(ST* pst)
{
    assert(pst);
    return pst->top;

3.所有代码 

以数组为例实现栈,分为头文件(Stack.h)和函数实现(Stack.c)以及测试(test.c)

Stack.h:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef int STDataType;

typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

//初始化栈
void STInit(ST* pst);
void STDestroy(ST* pst);

//入栈 出栈
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);

//取栈顶数据
STDataType STTop(ST* pst);

//判空
bool STEmpty(ST* pst);

//获取数据个数
int	STSize(ST* pst);

Stack.c:

#include"Stack.h"

//初始化栈
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;
	//top指向栈顶数据的下一个位置
	pst->top = 0;
	pst->capacity = 0;
}
void STDestroy(ST* pst)
{
	assert(pst);

	free(pst->a);
	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;
}

//入栈 出栈
void STPush(ST* pst, STDataType x)
{
	assert(pst);

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

		pst->a = tmp;
		pst->capacity = newcapacity;
	}
	pst->a[pst->top] = x;
	pst->top++;
}
void STPop(ST* pst)
{
	assert(pst);
	assert(pst->top > 0);
	pst->top--;
}

//取栈顶数据
STDataType STTop(ST* pst)
{
	assert(pst);
	return pst->a[pst->top - 1];
}

//判空
bool STEmpty(ST* pst)
{
	assert(pst);
	return pst->top == 0;
}

//获取数据个数
int	STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}

test.c

#include"Stack.h"
int main()
{
	ST s;
	STInit(&s);
	STPush(&s, 1);
	STPush(&s, 2);
	STPush(&s, 3);
	STPush(&s, 4);
	while (!STEmpty(&s))
	{
		printf("%d\n", STTop(&s));
		STPop(&s);
	}
	STDestroy(&s);
	return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1955226.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【无标题】shell脚本的基本命令+编写shell脚本

shell脚本 一.shell基础 1.shell概念 2.shell脚本 3.shell脚本编写注意事项 二.编写shell脚本 1.编写一个helloworld脚本&#xff0c;运行脚本 [rootshell ~]# vim helloworld.sh #!/bin/bash //声明 echo "hello world!" ls -lh /etc/ 运行脚本(四种方式)&…

react版本判断是否面包含

react-admin: react版本 import { useState,useEffect } from react import ./Secene.css import { Checkbox } from "antd"; import* as turf from turf/turf; import type { CheckboxProps } from antd; // const onChange: CheckboxProps[onChange] (e) >…

bugku-web-cookies

进来以后看到一个巨长的字符串, 源码同样,发现url后面是base64编码解码得keys.txt 还有一个line参数&#xff0c;修改并没有发生任何变化。我想不到要改keys.txt成index.php&#xff08;base64加密格式&#xff1a;aW5kZXgucGhw&#xff09; line1时&#xff1a; line2时&…

Linux系统编程(2):信号

Linux内核提供了各种各样的内核对象用于协调进程间的通讯&#xff0c;如信号、管道、消息队列等&#xff0c; 本章针对Linux内核的信号对象进行讲解。 1. 信号的基本概念 1.1. 概述 信号&#xff08;signal&#xff09;&#xff0c;又称为软中断信号&#xff0c;用于通知进程…

Go语言垃圾回收GC(完整)

垃圾回收的概念 GC(垃圾回收)是 Go 语言中的一个重要机制&#xff0c;用于自动管理内存 在 Go 语言中&#xff0c;GC 会自动发现和回收那些不再被使用的内存空间&#xff0c;从而防止内存泄漏和有 效利用内存。 内存垃圾怎样产生 程序在内存上被分为堆区、栈区、全局数据区、…

黑马头条vue2.0项目实战(一)——项目初始化

1. 图标素材&#xff08;iconfont简介&#xff09; 制作字体图标的工具有很多&#xff0c;推荐使用&#xff1a;iconfont-阿里巴巴矢量图标库。 注册账户 创建项目 可以根据项目自定义 class 前缀 上传图标到项目 生成链接&#xff0c;复制 css 代码&#xff0c;在项目中使用…

数组与链表谁访问更快

一、线性表 线性表是数据结构中的一种基本类型&#xff0c;它由一组线性排列的元素组成。线性表的特点是可以进行顺序访问&#xff0c;但不支持随机访问。 二、非线性表 非线性表是数据结构中另一种类型&#xff0c;如树和图&#xff0c;它们由多个节点组成&#xff0c;节点…

【云原生】Docker搭建知识库文档协作平台Confluence

目录 一、前言 二、企业级知识库文档工具部署形式 2.1 开源工具平台 2.1.1 开源工具优点 2.1.2 开源工具缺点 2.2 私有化部署 2.3 混合部署 三、如何选择合适的知识库平台工具 3.1 明确目标和需求 3.2 选择合适的知识库平台工具 四、Confluence介绍 4.2 confluence特…

链表篇: 01-从尾到头打印链表

解题思路: 直接往数组中加入数据&#xff0c;然后通过Java提供的工具类(coollections) 直接进行数组的反转。 代码实现: import java.util.*; /** * //ListNode 的数据结构 * * public class ListNode { * int val; * ListNode next null; * * …

韩顺平0基础学java——第39天

p820-841 jdbc和连接池 1.JDBC为访问不同的数据库提供了统一的接口&#xff0c;为使用者屏蔽了细节问题。 2.Java程序员使用JDBC&#xff0c;可以连接任何提供了JDBC驱动程序的数据库系统&#xff0c;从而完成对数据库的各种操作。 3.jdbc原理图 JDBC带来的好处 2.JDBC带来的…

10 Vue 特性要点

Vue2 特性要点 Vue2 源码理解 Vue 双向数据绑定 先从单向绑定切入单向绑定非常简单,就是把Mode1绑定到view,当我们用Javascript代码更新Model时, view就会自动更新 双向绑定就很容易联想到了,在单向绑定的基础上,用户更新了View, Mode1的数据也自动被更新了 因为 Vue 是数据双向…

手把手教你集成GraphRag.Net:打造智能图谱搜索系统

在人工智能和大数据发展的背景下&#xff0c;我们常常需要在项目中实现知识图谱的应用&#xff0c;以便快速、准确地检索和使用信息。 今天&#xff0c;我将向大家详细介绍如何在一个新的.NET项目中集成GraphRag.Net&#xff0c;这是一个参考GraphRag实现的.NET版本&#xff0c…

Flutter——全网最精致木鱼APP可上架应用市场

研发背景 工作之余&#xff0c;闲来无事&#xff0c;想着研发一款用户可能会经常用到的一款APP,并且能够顺便掌握一下Flutter Material Design 3 UI&#xff0c;所以就有了这款比较精致的木鱼APP的诞生。 开源代码 https://github.com/z244370114/woodenfish

YOLOV8源码解读-C2f模块-以及总结c2模块、Bottleneck

c2f模块是对c2模块的改进 c2模块图解解读 先给出YOLOV8中卷积的定义模块一键三连-卷积-BN-激活函数 def autopad(k, pNone, d1): # kernel, padding, dilation"""Pad to same shape outputs."""if d > 1:k d * (k - 1) 1 if isinstance…

linux练习2

一、搭建nfs服务器&#xff0c;客户端可从服务端/share目录上传与下载文件 **服务端** 1、下载相关安装包 [rootserver ~]# yum install rpcbind -y [rootserver ~]# yum install nfs-utils -y 2、 创建共享文件夹/share并授予权限 [rootserver ~]# mkdir /share [rootserv…

结构体笔记

结构体 C语言中的数据类型&#xff1a; 基本数据类型&#xff1a;char/int/short/double/float/long 构造数据类型&#xff1a;数组&#xff0c;指针&#xff0c;结构体&#xff0c;共用体&#xff0c;枚举 概念&#xff1a; 结构体是用户自定义的一种数据类型&#xff0c…

【七】Hadoop3.3.4基于ubuntu24的分布式集群安装

文章目录 1. 下载和准备工作1.1 安装包下载1.2 前提条件 2. 安装过程STEP 1: 解压并配置Hadoop选择环境变量添加位置的原则检查环境变量是否生效 STEP 2: 配置Hadoop2.1. 修改core-site.xml2.2. 修改hdfs-site.xml2.3. 修改mapred-site.xml2.4. 修改yarn-site.xml2.5. 修改hado…

全球相机控制面板市场展望与未来增长机遇:预计未来六年年复合增长率CAGR为4.3%

在全球摄影器材和专业影像设备需求增长的背景下&#xff0c;相机控制面板正成为市场的焦点。本文详细分析了全球相机控制面板市场的现状、增长趋势及未来前景&#xff0c;旨在为投资者和业内人士提供深入的市场洞察和指导。 市场概览 据恒州诚思团队研究分析显示&#xff0c;2…