C语言实现栈--数据结构

这篇具有很好参考价值的文章主要介绍了C语言实现栈--数据结构。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C语言实现栈--数据结构

  • 魔王的介绍:😶‍🌫️一名双非本科大一小白。
  • 魔王的目标:🤯努力赶上周围卷王的脚步。
  • 魔王的主页:🔥🔥🔥大魔王.🔥🔥🔥
    C语言实现栈--数据结构
    ❤️‍🔥大魔王与你分享:“断剑重铸的锐雯败于菲奥娜,原来破镜重圆的爱到处都是破绽”。

一、前言

1、介绍

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

C语言实现栈--数据结构

2、说明

栈的实现可以采用顺序表或链表,顺序表就是按顺序存进去(尾插),然后出的时候需要从后往前出。链表的话我们一边采用头插,因为如果是尾插的话,还要有前一个的地址,比头插麻烦一点,所以链表实现一般采用头插。
相对来说数组(顺序表)实现更优一些,因为数组在尾上插入数据代价更小。
如果顺序表和链表你已经掌握,那么相信栈和队列对你来说都是很简单的,因为它们只是对顺序表和链表进行特殊处理而已。

  • 本篇将通过顺序表实现栈。

二、栈的实现

1、创建结构体

我们需要创建一个结构体来存放数组指针和该数组的元素个数及数组的容量。

代码:

typedef int STDateType;

typedef struct Stack
{
	STDateType* a;
	int top;//如果初始化为0,可以理解为元素个数(也就是栈顶元素下标+1),如果初始化为-1,可以理解为栈顶元素的下标
	int capacity;
}ST;

2、初始化和销毁

初始化:
就像顺序表一样,我们需要首先开辟一个初始空间,然后不够的时候在扩容。
销毁:
因为空间是malloc在堆区申请出来的,所以需要我们进行手动释放,防止内存泄露。

代码:

//初始化和最后销毁
void STInit(ST* ps)
{
	assert(ps);
	ps->a = (STDateType*)malloc(sizeof(ST) * 5);
	if (ps->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	ps->top = 0;
	ps->capacity = 5;
}
void STDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->capacity = 0;
	ps->a = NULL;
	1.没有让top也就是栈顶位置重置。
	ps->top = 0;
	//最后在Test.c上让结构体指针指向空。
}

3、入栈

入栈只能从栈顶入。

//入栈
void STPush(ST* ps, STDateType x)
{
	assert(ps);
	if (ps->top == ps->capacity) //判断是否满了
	{
		STDateType* temp = (STDateType*)realloc(ps->a, ps->capacity * sizeof(ST) * 2);
		if (temp == NULL)
		{
			perror("realloc fail");
			return;
		}
		else
		{
			ps->a = temp;
			ps->capacity *= 2;
			temp = NULL;
		}
	}
	ps->a[ps->top] = x;
	ps->top++;
}

4、出栈

直接减1就行。

//出栈
void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));
	ps->top--;
}

5、元素个数

就等于我们结构体里记录数据个数的值。

//元素个数
int STSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

6、判断是否为空

为什么这些简单的操作也要封装成函数呢?
因为编写函数的肯定是一个人,但是使用函数的人并不知道创建的具体是什么,比如结构体里的那个记录元素个数的,可能另一个人编写的时候该变量是记录栈顶下标的,那么就会总是比总个数小1,所以使用者并不能判断到底是哪个,所以需要编写函数的人把每个单独的功能都尽可能封装成函数,当使用者使用时,不需要区分那么多,直接调用对应函数,就能得到想要的结果。

代码:

//判断是否为空
bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

7、栈顶元素

同上一个的描述,因为不知道记录的是栈顶元素的下标还是元素的总个数,所以为了方便且避免出错,需要封装成函数让使用者使用。

//栈顶元素
STDateType STTop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));
	return ps->a[ps->top - 1];
}

三、总代码

Stack.h

`Stack.h

  #pragma once

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

typedef int STDateType;

typedef struct Stack
{
	STDateType* a;
	int top;//如果初始化为0,可以理解为元素个数(也就是栈顶元素下标+1),如果初始化为-1,可以理解为栈顶元素的下标
	int capacity;
}ST;

//初始化和最后销毁
void STInit(ST* ps);
void STDestory(ST* ps);

//入栈
void STPush(ST* ps, STDateType x);

//出栈
void STPop(ST* ps);

//元素个数
int STSize(ST* ps);

//判断是否为空
bool STEmpty(ST* ps);

//栈顶元素
STDateType STTop(ST* ps);

Stack.c

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Stack.h"

//初始化和最后销毁
void STInit(ST* ps)
{
	assert(ps);
	//ps->a = malloc(sizeof(ST) * 5);  1.没有强转
	ps->a = (STDateType*)malloc(sizeof(ST) * 5);
	2.开辟新空间后没有检查
	if (ps->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	ps->top = 0;
	ps->capacity = 5;
}
void STDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->capacity = 0;
	ps->a = NULL;
	1.没有让top也就是栈顶位置重置。
	ps->top = 0;
	//最后在Test.c上让结构体指针指向空。
}

//入栈
void STPush(ST* ps, STDateType x)
{
	assert(ps);
	//if (ps->top == ps->capacity)
	//{
	//	ST* str = realloc(ps->a, ps->capacity * sizeof(ST) * 2);
	//	if (str == NULL)
	//	{
	//		perror("realloc fail");
	//		return;
	//	}
	//}  
	1.没有把扩容的时候创建的新指针赋给原指针
	if (ps->top == ps->capacity) //判断是否满了
	{
		//ST* temp = realloc(ps->a, ps->capacity * sizeof(ST) * 2);
		//2.指针应该指向数据的类型的地址,而且realloc也没强转为数据类型的指针
		STDateType* temp = (STDateType*)realloc(ps->a, ps->capacity * sizeof(ST) * 2);
		if (temp == NULL)
		{
			perror("realloc fail");
			return;
		}
		else
		{
			ps->a = temp;
			3.忘记让结构体内的容量*2
			ps->capacity *= 2;
			temp = NULL;
		}
	}
	ps->a[ps->top] = x;
	ps->top++;
}

//出栈
void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));
	ps->top--;
}

//元素个数
int STSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

//判断是否为空
bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

//栈顶元素
STDateType STTop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));
	return ps->a[ps->top - 1];
}

Test.c

Test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Stack.h"

int main()
{
	ST ps;
	STInit(&ps);
	STPush(&ps, 0);
	STPush(&ps, 1);
	STPush(&ps, 2);
	STPush(&ps, 3);
	STPush(&ps, 4);

	//打印,因为只能从栈顶出,所以每打印一个数据就需要弹出这个数据(出栈)。

	while (!STEmpty(&ps))
	{
		printf("%d ", STTop(&ps));
		STPop(&ps);//打印和出栈是一对,因为想要打印下一个,那么栈顶的元素必须出栈
	}
	STDestory(&ps);
	ps.a = NULL;
	return 0;
}

四、总结

C语言实现栈--数据结构

✨请点击下面进入主页关注大魔王
如果感觉对你有用的话,就点我进入主页关注我吧!文章来源地址https://www.toymoban.com/news/detail-421540.html

到了这里,关于C语言实现栈--数据结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言实现队列--数据结构

    😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️Take your time ! 😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️ 💥个人主页:🔥🔥🔥大魔王🔥🔥🔥 💥所属专栏:🔥魔王的修炼之路–数据结构🔥 如果你觉得这篇文章对你有帮助,请在文章结尾处留下你的 点赞 👍和 关注 💖,支持一

    2024年02月05日
    浏览(45)
  • 数据结构 栈(C语言实现)

            时间就是生命,时间就是速度,时间就是气力。——郭沫若;本章继续学习数据结构,本章主要讲了什么是栈以及栈的基本功能和实现方法。    话不多说安全带系好,发车啦 (建议电脑观看) 。 附:红色,部分为重点部分;蓝颜色为需要记忆的部分(不是死记

    2024年02月09日
    浏览(40)
  • 数据结构:队列(Python语言实现)

    队列是一种 先进先出 的数据结构(特殊的线性结构),在队列 尾部 插入新元素,在队列 头部 删除元素。 一般队列的基本操作如下: create:创建空队列。 enqueue:将新元素加入队列的尾部,返回新队列。 dequeue:删除队列头部元素,返回新队列。 front:返回队列头部的元素

    2024年02月13日
    浏览(45)
  • 堆--C语言实现数据结构

    本期带大家一起用C语言实现堆🌈🌈🌈 堆(Heap)是一种特殊的树状数据结构,它是一种完全二叉树。堆被广泛应用于优先队列、排序算法等领域。 堆的特点: 堆分为最大堆和最小堆两种类型。最大堆中,父节点的值大于或等于其子节点的值;最小堆中,父节点的值小于或

    2024年02月16日
    浏览(37)
  • 栈--C语言实现数据结构

    本期带大家一起用C语言实现栈🌈🌈🌈 栈是一种常见的数据结构,它遵循后进先出(Last In, First Out)的原则。可以将其类比为现实生活中的一摞书或者一叠盘子。 栈由一个连续的内存区域组成,可以存储一系列的元素。在栈的一端称为栈顶,另一端称为栈底。 栈的主要操作

    2024年02月16日
    浏览(40)
  • 数据结构——堆(C语言实现)

    堆是一种特殊的数据结构,它是一棵完全二叉树,同时满足堆属性,即父节点的值总是大于或小于其子节点的值。如果父节点的值总是大于子节点的值,那么我们称之为大根堆;反之,如果父节点的值总是小于子节点的值,那么我们称之为小根堆。在堆中,根节点的值最大(

    2024年02月08日
    浏览(39)
  • 数据结构初阶(用C语言实现简单数据结构)--栈和队列

    ✨✨欢迎来到T_X_Parallel的博客!!       🛰️博客主页:T_X_Parallel       🛰️专栏 : 数据结构初阶       🛰️欢迎关注:👍点赞🙌收藏✍️留言 这小猫真好看 言归正传,通过上篇有关顺序表和链表的博客,可以了解到线性表的一些大致特征,这篇博

    2024年02月08日
    浏览(42)
  • 数据结构链表(C语言实现)

            机遇对于有准备的头脑有特别的亲和力。本章将讲写到链表其中主要将写到单链表和带头双向循环链表的如何实现。    话不多说安全带系好,发车啦 (建议电脑观看) 。 附:红色,部分为重点部分;蓝颜色为需要记忆的部分(不是死记硬背哈,多敲);黑色加粗

    2024年02月10日
    浏览(40)
  • C语言实现链表--数据结构

    魔王的介绍:😶‍🌫️一名双非本科大一小白。 魔王的目标:🤯努力赶上周围卷王的脚步。 魔王的主页:🔥🔥🔥大魔王.🔥🔥🔥 ❤️‍🔥大魔王与你分享:很喜欢宫崎骏说的一句话:“不要轻易去依赖一个人,它会成为你的习惯当分别来临,你失去的不是某个人而是你精

    2024年02月02日
    浏览(42)
  • 【数据结构】栈的实现(C语言)

    文章目录 1.栈 1.1 栈的定义 1.2 C语言实现栈 1.2.1接口函数 1.2.2栈的创建 1.2.3栈的初始化  1.2.4栈的销毁 1.2.5压栈 1.2.6出栈 1.2.7判断栈是否为空 1.2.8取栈顶元素 1.2.9 栈有多少个数据  1.3 C语言实现栈的具体代码 头文件stack.h 接口函数stack.c 测试函数test.c         栈(stack)又名堆

    2024年02月05日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包