<栈>的概念结构实现【C语言版】

news/2024/5/20 6:45:01 标签: 数据结构, c语言, 顺序表

 

1.栈的概念及结构

栈存储数据的方式跟数组一样,都是将元素排成一行。只不过它还有以下 3 条约束。

  ● 只能在末尾插入数据。
  ● 只能读取末尾的数据。
  ● 只能移除末尾的数据。

你可以将栈看成一叠碟子:你只能看到最顶端那只碟子的碟面,其他都看不到。另外,要加碟子只能往上加,不能往中间塞,要拿碟子只能从上面拿,不能从中间拿(至少你不应该这么做)。绝大部分计算机科学家都把栈的末尾称为栈顶,把栈的开头称为栈底。

尽管这些约束看上去令人很拘束,但很快你就会发现它们带来的好处。

我们先从一个空栈开始演示。

往栈里插入数据,也叫作压栈。你可以想象把一个碟子压在其他碟子上的画面。

首先,将 5 压入栈中。

接着,将 3 压入栈中。

再将 0 压入栈中。

注意,每次压栈都是把数据加到栈顶(也就是栈的末尾)。如果想把 0 插入到栈底或中间,那是不允许的,因为这就是栈的特性:只能在末尾插入数据。

从栈顶移除数据叫作出栈。这也是栈的限制:只能移除末尾的数据。

来把栈中的一些数据弹出。

首先,弹出 0。 

接着,弹出 3。

这就剩下 5了。 

总结:

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

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

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


2.栈的实现

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

2.1栈的结构定义

typedef int STDataType;

typedef struct Stack
{
	STDataType* a;  //动态开辟数组
	int capacity; //记录栈的容量大小
	int top; //记录栈顶的位置
}Stack;

2.2函数接口的实现

首先是在Stack.h文件中进行函数声明

Stack.h

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

typedef int STDataType;

typedef struct Stack
{
	STDataType* a;  //动态开辟数组
	int capacity; //记录栈的容量大小
	int top; //记录栈顶的位置
}Stack;

//栈的初始化
void StackInit(Stack* ps);
//释放动态开辟的内存
void StackDestroy(Stack* ps);
//压栈
void StackPush(Stack* ps, STDataType data);
//出栈
void StackPop(Stack* ps);
//读取栈顶的元素
STDataType StackTop(Stack* ps);
//判断栈是否为空
bool StackEmpty(Stack* ps);
//栈存储的数据个数
int StackSize(Stack* ps);

在Stack.c文件中进行函数的定义

Stack.c

#define _CRT_SECURE_NO_DEPRECATE 1
#include"Stack.h"

void StackInit(Stack* ps)
{
	assert(ps);
	//初始化时,可附初值,也可置空
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void StackDestroy(Stack* ps)
{
	assert(ps);
	//若并未对ps->a申请内存,则无需释放
	if (ps->capacity == 0)
		return;
	//释放
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

void StackPush(Stack* ps,STDataType data)
{
	assert(ps);
	//若容量大小等于数据个数,则说明栈已满,需扩容
	if (ps->capacity == ps->top)
	{
		//若为第一次扩容,则大小为4,否则每次扩大2倍
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}

		ps->a = tmp;
		ps->capacity = newCapacity;
	}
	//压栈
	ps->a[ps->top] = data;
	ps->top++;
}

void StackPop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	//出栈
	ps->top--;
}

STDataType StackTop(Stack* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	//返回栈顶的数据
	return ps->a[ps->top - 1];
}

bool StackEmpty(Stack* ps)
{
	assert(ps);
	//返回top
	return ps->top == 0;
}

int StackSize(Stack* ps)
{
	assert(ps);
	return ps->top;
}


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

相关文章

使用 tslib 库

tslib 是专门为触摸屏设备所开发的 Linux 应用层函数库&#xff0c;并且是开源。tslib 为触摸屏驱动和应用层之间的适配层&#xff0c; 它把应用程序中读取触摸屏 struct input_event 类型数据&#xff08;这是输入设备上报给应用层的原始数据&#xff09;并进行解析的操作过程…

蓝眼人问题

问题描述 \qquad在一座小岛上住着100名居民&#xff0c;每个居民要么是黑眼睛&#xff0c;要么是蓝眼睛。黑眼睛的人有95个&#xff0c;蓝眼睛的人有5个。 \qquad有一天早上&#xff0c;岛上的族长宣布&#xff1a;“岛上凡是蓝眼睛的人&#xff0c;可以在下午搭乘小船在下出海…

【Linux】版本管理工具 Git

目录 一、什么是 Git 二、如何使用 Git 1、创建远程仓库 2、将远端仓库克隆到本地 3、将本地文件添加到仓库 3.1、三板斧第一招&#xff1a;文件添加 3.2、三板斧第二招&#xff1a;提交本地 3.3、三板斧第三招&#xff1a;提交远端 4、删除文件 5、删除仓库 一、什么是 Gi…

DBCO-PEG-Methacrylate_DBCO-PEG-MA_二苯并环辛炔-PEG-甲基丙烯酸酯

一、试剂基团反应特点&#xff08;Reagent group reaction characteristics&#xff09;&#xff1a;DBCO&#xff08;二苯并环辛炔&#xff09;是一种环炔烃&#xff0c;可以通过在水溶液中通过应变促进的1,3-偶极环加成反应与叠氮化物反应&#xff0c;这种生物正交反应也称为…

剑指offer

剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字。 在一个长度为 n 的数组 nums 里的所有数字都在 0&#xff5e;n-1 的范围内。数组中某些数字是重复的&#xff0c;但不知道有几个数字重复了&#xff0c;也不知道每个数字重复了几次。请找出数组中任意一个重复的数字…

ES6 课程概述⑥

文章目录渲染函数基础节点、树、以及虚拟 DOM虚拟 DOMcreateElement 参数深入数据对象使用 JavaScript 代替模板功能v-if 和 v-forv-model事件&按键修饰符插槽JSX插值指令v-textv-htmlv-showv-ifv-forv-onv-bindv-modelv-slotv-prev-cloakv-onceRef自定义指令过滤器插槽函数…

C语言萌新如何使用printf函数?

&#x1f40e;作者的话 如果你搜索输入输出函数&#xff0c;那么你会看到输入输出流、Turbo标准库、标准输出端、stdout什么什么乱七八糟的&#xff0c;作为一个萌新&#xff0c;哪懂这些&#xff1f; 本文介绍萌新在前期的学习中&#xff0c;常用的输入输出函数及其功能~ 跳跃…

记2022年秋招经历

自我介绍求职体验求职心得 一、自我介绍 学历普通本科&#xff0c;专业是网络工程&#xff0c;在校期间学习主要的是计算机体系方面的知识&#xff0c;根据课程&#xff0c;自学过前端、后端等内容。包括前端三板斧(htmlcssjs)、常用的前端框架(bootstarp/Vue等&#xff09;&am…