【数据结构与算法】栈(Stack)之 浅谈数组和链表实现栈各自的优缺点

news2024/12/23 22:41:37

文章目录

  • 1.栈介绍
  • 2. 哪种结构实现栈会更优?
  • 3.栈代码实现(C语言)

往期相关文章:

  1. 线性表之顺序表
  2. 线性表之链表

1.栈介绍

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

  1. 栈的插入操作(Push):称为压栈 或 入栈 或 进栈。
  2. 栈的删除操作(Pop):也叫出栈 或 弹栈。

在这里插入图片描述
  栈顶(top)也可以是最后一次进栈的数据位置,比如上图中,栈顶可以分别是100、200、300的位置,这取决于栈顶初始化成 0 还是 -1。如果栈顶最开始初始化为0,则栈顶是如上图所演示的位置,因为是先Push,然后再栈底top++;如果栈顶初始化为-1,则栈顶是最后一次进栈的数据下标位置,因为是先top++,然后再Push。

2. 哪种结构实现栈会更优?

  栈的实现一般可以使用数组或链表实现。对栈而言数组的结构实现更优一些,因为数组在尾上插入和删除数据的代价很小,时间复杂度均为O(1),且没有其它额外开销。下面具体分析两种结构实现栈的优缺点。

对于链表实现栈,问题很多。一是链表有八种,二是每种链表实现起来都存在缺点。下面简单分析下链表实现栈的问题:

  1. 先说单向链表实现栈,即便是多维护一个尾指针,对于栈的删除操作还是需要遍历,因为需要找到尾节点的上一个节点。

  2. 而对于双向链表,为了解决单向链表实现栈的删除操作问题,唯一可行的只有双向循环链表,不仅轻松地找到尾结点,同时还能找到上一个节点,确实能解决上面谈到的问题。不过这又有其它问题了,每个节点相比于单向链表都多维护了一个指针变量,有一定内存开销。

所以说实现栈的最优结构,还得是数组,且数组自身的特性也产生了几个优点。数组的存储是连续的,正是因为这个原因:

  1. 数组的寄存器命中率比链表高
  2. 寄存器命中后,不会产生寄存器空间污染

数组实现栈的话就没有任何缺点吗?答案是有的,前面也说过,栈是一种特殊的线性表。

  1. 空间给大了或每次扩容扩大了,然后又不使用,那空间就浪费了;4
  2. 空间给小了或者每次扩容扩小了,那插入数据时容量不够经常需要扩容(realloc),扩容本身也有一些消耗
  3. 最不能接受的是,如果后面的内存不足以扩容设定的大小,realloc扩容可能会异地扩容,内存碎片增多,异地扩容意思是跳过这段大小不够的内存空间,到另一片内存区域扩容,这也会导致跳过的那一段内存变成内存碎片,如果一直没有程序去使用,空间也浪费掉了!关于realloc扩容,可以看看我的这篇文章 指针与动态内存 2.3realloc部分。

不过上述数组的缺点,也是能控制的。比如数组初始化大小根据需求给一个折中,扩容方案也折中,比如按自身1.5倍扩,这样能控制扩容的频率不至于太频繁,异地扩容的几率也小一些!优点相比于缺点,利大于弊!最重要的是,比起链表的优缺点,也要好上许多!

3.栈代码实现(C语言)

stack.h

#pragma once

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

typedef int valuetype;

typedef struct {
	valuetype* arr;
	int top;
	int capacity;
} Stack;

void Init(Stack* stack);

void Push(Stack* stack, valuetype value);
void Pop(Stack* stack);

valuetype Top(Stack* stack);
int Size(Stack* stack);
bool Empty(Stack* stack);

void Destroy(Stack* stack);

stack.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Stack.h"

void Init(Stack* stack) {
	assert(stack);
	stack->arr = NULL;
	stack->capacity = stack->top = 0;
}

void Push(Stack* stack, valuetype value) {
	assert(stack);
	if (stack->top == stack->capacity) {
		stack->capacity = stack->capacity == 0 ? 10 : (int)(stack->capacity * 1.5);
		stack->arr = (valuetype*)realloc(stack->arr, sizeof(valuetype) * stack->capacity);
		if (stack->arr == NULL) {
			perror("realloc failed in the function Push(Stack*, valuetype).");
			return;
		}
	}
	stack->arr[stack->top++] = value;
}

void Pop(Stack* stack) {
	assert(stack && stack->top > 0);
	stack->top--;
}

valuetype Top(Stack* stack) {
	assert(stack && stack->top > 0);
	return stack->arr[stack->top - 1];
}

int Size(Stack* stack) {
	assert(stack);
	return stack->top;
}

bool Empty(Stack* stack) {
	assert(stack);
	return stack->top == 0;
}

void Destroy(Stack* stack) {
	assert(stack);
	free(stack->arr);
	stack->arr = NULL;
	stack->capacity = stack->top = 0;
}

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

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

相关文章

Toolbar

记录一下遇到的问题 Toolbal 使用过程中左右出现间隙 代码&#xff1a; <com.google.android.material.appbar.AppBarLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:t…

SAP 消息编号 KI235

在执行AFAB折旧运行的时候&#xff0c;折旧没有运行出来 通过AFBP查询&#xff0c;出现一下报错 原因是因为在ASCET当中没有配置科目分配对象&#xff0c;所以系统无法把折旧费和CO&#xff08;成本中心&#xff09;关联起来 “科目设置”必选勾选 重新运行AFAB &#xff0c;就…

【新书推荐】2.4节 数据宽度

本节内容&#xff1a;计算机受制于物理器件的制约&#xff0c;存储或读写数据的宽度是有长度限制的&#xff0c;通常我们使用数据位的位数来表示数据宽度&#xff0c;如8位、16位、32位、64位等。 ■计算机计数与数学计数的区别&#xff1a;数学中的数据可以是无穷大或无穷小&a…

01.领域驱动设计:微服务设计为什么要选择DDD学习总结

目录 1、前言 2、软件架构模式的演进 3、微服务设计和拆分的困境 4、为什么 DDD适合微服务 5、DDD与微服务的关系 6、总结 1、前言 我们知道&#xff0c;微服务设计过程中往往会面临边界如何划定的问题&#xff0c;不同的人会根据自己对微服务的理 解而拆分出不同的微服…

解读IP风险画像标签:深度洞察网络安全

在当今数字化的世界中&#xff0c;网络安全成为企业和个人关注的焦点。IP风险画像标签作为网络安全的利器&#xff0c;扮演着深度洞察网络风险的角色。本文将深入解读IP风险画像标签&#xff0c;揭示其在网络安全领域的重要性和功能。 1. IP风险画像标签是什么&#xff1f; I…

Kubernetes/k8s之安全机制:

k8s当中的安全机制 核心是分布式集群管理工具&#xff0c;容器编排&#xff0c;安全机制核心是:API SERVER作为整个集群内部通信的中介&#xff0c;也是外部控制的入口&#xff0c;所有的安全机制都是围绕api server开设计的。 请求api资源 1、认证 2、鉴权 3、准入机制 三…

Java设计模式-装饰器模式(10)

大家好,我是馆长!今天开始我们讲的是结构型模式中的装饰器模式。老规矩,讲解之前再次熟悉下结构型模式包含:代理模式、适配器模式、桥接模式、装饰器模式、外观模式、享元模式、组合模式,共7种设计模式。。 装饰器模式(Decorator Pattern) 定义 装饰(Decorator)模式…

npm安装卡住问题(最新版)

npm安装卡住问题(最新版) 背景&#xff1a; ​ 最近这两天用npm安装一些包的时候&#xff0c;发现一直卡住&#xff1a; 报错&#xff1a; idealTree:npm: sill idealTree buildDeps之前能用的现在不能用了&#xff0c;我一想&#xff0c;是不是源头的问题&#xff0c;还真是…

软考复习之UML设计篇

UML统一建模语言 构件图&#xff1a;描述系统的物理结构&#xff0c;它可以用来显示程序代码如何分解成模块 部署图&#xff1a;描述系统中硬件和软件的物理结构&#xff0c;它描述构成系统架构的软件构件&#xff0c;处理器和设备 用例图&#xff1a;描述系统与外部系统及用…

链表--104. 二叉树的最大深度/medium 理解度A

104. 二叉树的最大深度 1、题目2、题目分析3、复杂度最优解代码示例4、适用场景 1、题目 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,n…

谷粒商城配置虚拟机

一、创建虚拟机 之前有在VM里面建一个ubuntu的虚拟机&#xff0c;准备拿来直接用&#xff0c;网络设置为NAT模式&#xff0c;查看我的虚拟机是虚拟机&#xff1a;192.168.248.128 主机&#xff1a; 192.168.2.12。可以互相ping通。 二、linux安装docker Docker docker是虚拟…

OpenTCS IDEA 全流程搭建和运行指南

OpenTCS IDEA 全流程搭建和运行指南 JDK安装下载JDK版本 openTCS源码下载IDEA 打开运行查看下载源码中gradle版本号下载gradle 二进制文件配置IDEA Gradle本地仓库IDEA打开openTCS项目运行顺序 JDK安装 下载JDK版本 JDK网址 注意&#xff1a; 请下载官方文档标准的java13JDK o…

C语言零基础入门第2天《 visual studio下载安装教程和搭建开发环境及踩坑指南》(保姆级图文教程)

visual studio下载安装教程和搭建开发环境 1、 项目实战效果图2、简单了解一下目前主流的开发环境3、 visual studio下载地址4、 visual studio安装教程5、 配置visual studio环境变量 6、如何新建一个C项目7、新建第一个C程序8、用代码测试创建的项目是否可用8、如何成功让代码…

vue解决:Parsing error: No Babel config file detected for

解决babel配置问题 报错信息如下&#xff1a; Parsing error: No Babel config file detected for C:\Users\yjj\Desktop\大学\大二\学习\vue_ bags \slot_ study\src\App. vue. Either disable config file checking withrequireConfigFile: false, or configure Babel so tha…

《游戏-01_3D-开发》之—人物动画控制器

创建变量&#xff0c; 创建线&#xff0c; 连接&#xff0c; 选中线会变为蓝色&#xff0c;新增变量&#xff0c; 设置线&#xff0c; 双击子层进入子层&#xff0c; 创建变量&#xff0c; 双击SkillPanel 拖拽好之后返回上一层&#xff0c; 依次连接&#xff0c; 设置线&#…

凭服务出圈的海底捞,竟然在这件事上也很卷

1月9日&#xff0c;法大大与企业绿色发展研究院联合发布了《2023年签约减碳与低碳办公白皮书》&#xff08;点击阅读及下载&#xff1a;法大大推出“签约减碳”年度账单&#xff0c;引领低碳办公新风潮&#xff09;&#xff0c;该白皮书基于《低碳办公评价》标准倡导的创新减碳…

图像分类】【深度学习】【轻量级网络】【Pytorch版本】EfficientNet_V2模型算法详解

【图像分类】【深度学习】【轻量级网络】【Pytorch版本】EfficientNet_V2模型算法详解 文章目录 【图像分类】【深度学习】【轻量级网络】【Pytorch版本】EfficientNet_V2模型算法详解前言EfficientNet_V2讲解自适应正则化的渐进学习(Progressive Learning with adaptive Regul…

《如何画好架构图》学习笔记

看了一堂《如何画好架构图》的公开课&#xff0c;结合网上的资料与经验做一些思考总结。文中的例子和图片大多是从课程中摘录的。 1. 4R架构定义 4R架构定义其实是软件架构定义经过归纳提炼后的简称。 软件架构定义&#xff1a;软件架构是指软件系统的顶层&#xff08;Rank&am…

Vue好看的组件库:Element

文章目录 1、什么是Element2、Element快速入门3、Element布局3.1、 Layout 局部3.2、容器布局 1、什么是Element Element&#xff1a;是饿了么公司前端开发团队提供的一套基于 Vue 的网站组件库&#xff0c;用于快速构建网页 Element 提供了很多组件&#xff08;组成网页的部件…

2024-01-24(ElasticSearch)

1.mysql和elasticsearch的架构&#xff1a; 2.IK分词器利于分中文词汇。 底层是有一个中文字典&#xff0c;这个字典中的中文词汇也是可以拓展的和禁用某些词。 3.mapping常见属性&#xff1a; type&#xff1a;数据类型 index&#xff1a;是否索引 analyzer&#xff1a;分…