C 语言数据结构中的堆与栈:深入理解与应用

目录

1 栈(Stack)

1.1 定义与特性

1.2 内存中的栈

1.3 栈的应用

1.4 代码示例:栈的实现

2 堆(Heap)

2.1 定义与特性

2.2 堆的应用

2.3 C 语言中的堆操作

3 总结


        在 C 语言的世界里,堆(Heap)和栈(Stack)是两种非常重要且基础的数据结构,它们不仅在内存管理中扮演着核心角色,还广泛应用于算法和数据结构的实现中。本文将深入探讨 C 语言中堆与栈的概念、特性、区别以及它们在实际编程中的应用,并通过具体的代码示例来加深理解。

1 栈(Stack)

1.1 定义与特性

        栈是一种后进先出(LIFO, Last In First Out)的数据结构。它只允许在栈顶进行添加(push)或删除(pop)元素的操作。栈的操作具有高度的限制性,但这种限制也带来了操作的简单性和高效性。

1.2 内存中的栈

        在 C 语言程序中,函数调用时创建的局部变量、函数参数等通常存储在栈上。每当函数被调用时,它的执行环境和局部变量就会被压入调用栈(Call Stack)中;当函数返回时,其执行环境和局部变量会从栈中弹出

1.3 栈的应用

        函数调用与返回:调用栈用于存储函数调用时的上下文信息,包括返回地址、局部变量等。

        表达式求值:利用栈可以方便地实现算术表达式的求值,如中缀表达式转后缀表达式并利用栈求值。

        括号匹配:在解析代码或文本时,可以使用栈来检查括号的匹配情况。

1.4 代码示例:栈的实现

        以下是一个简单的栈实现示例,使用数组模拟栈结构:

#include <stdio.h>  
#include <stdlib.h>  
#include <stdbool.h>  #define MAX_SIZE 100  typedef struct {  int items[MAX_SIZE];  int top;  
} Stack;  // 初始化栈  
void initStack(Stack *s) {  s->top = -1;  
}  // 检查栈是否为空  
bool isEmpty(Stack *s) {  return s->top == -1;  
}  // 入栈  
bool push(Stack *s, int item) {  if (s->top == MAX_SIZE - 1) {  return false; // 栈满  }  s->items[++s->top] = item;  return true;  
}  // 出栈  
bool pop(Stack *s, int *item) {  if (isEmpty(s)) {  return false; // 栈空  }  *item = s->items[s->top--];  return true;  
}  // 主函数测试栈操作  
int main() {  Stack s;  initStack(&s);  push(&s, 1);  push(&s, 2);  int item;  pop(&s, &item);  printf("Popped item: %d\n", item); // 输出 2  return 0;  
}

2 堆(Heap)

2.1 定义与特性

        堆是一种特殊的完全二叉树结构,它满足堆属性:即子节点的键值或索引总是小于(或大于)它的父节点。根据堆属性的不同,堆可以分为最大堆和最小堆。堆通常通过数组来实现,以保持元素的紧密存储和高效访问。

2.2 堆的应用

        优先队列:堆是实现优先队列的理想数据结构,可以快速访问到队列中的最大或最小元素。

        堆排序:利用堆的特性进行排序的一种高效算法。

        图算法中的最短路径查找:如 Dijkstra 算法,使用最小堆来优化查找下一个最短路径节点的过程。

2.3 C 语言中的堆操作

        C 语言标准库中没有直接提供堆的操作函数,但可以通过数组和一系列函数来模拟堆的行为。以下是一个简单的最小堆实现框架(不包括所有细节):

// 假设已经有一个足够大的数组heap用于存储堆元素  
// 以下是一些堆操作的基本框架  // 向上调整堆  
void heapifyUp(int heap[], int index, int size) {  // 实现向上调整的逻辑  
}  // 向下调整堆  
void heapifyDown(int heap[], int index, int size) {  int smallest = index;  int left = 2 * index + 1;  int right = 2 * index + 2;  if (left < size && heap[left] < heap[smallest])  smallest = left;  if (right < size && heap[right] < heap[smallest])  smallest = right;  if (smallest != index) {  swap(heap[index], heap[smallest]);  heapifyDown(heap, smallest, size);  }  
}  // 插入元素  
void insert(int heap[], int *size, int item) {  heap[*size] = item;  ++(*size);  heapifyUp(heap, *size - 1, *size); // 注意:这里通常不需要,因为新元素总是放在末尾  // 或者直接调用heapifyDown来调整新加入的元素  
}  // 提取堆顶元素(最小元素)  
int extractMin(int heap[], int *size) {  if (*size <= 0) return INT_MAX; // 或其他错误处理  int root = heap[0];  heap[0] = heap[*size - 1];  --(*size);  heapifyDown(heap, 0, *size);  return root;  
}  // 注意:以上代码仅为框架,具体实现时需要根据实际情况调整

3 总结

        堆和栈是 C 语言中两种基础且重要的数据结构,它们在内存管理、算法实现等多个方面发挥着关键作用。通过深入理解它们的概念、特性和应用,我们可以更好地编写高效、可维护的 C 语言程序。希望本文能够帮助你更好地掌握堆与栈的知识,并在实际编程中灵活运用。

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

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

相关文章

[网络][CISCO]Cisco-PIX配置详解

Cisco PIX防火墙配置指南 任何企业安全策略的一个主要部分都是实现和维护防火墙&#xff0c;因此防火墙在网络安全的实现当中扮演着重要的角色。防火墙通常位于企业网络的边缘&#xff0c;使内部网络与Internet之间或与其他外部网络互相隔离&#xff0c;并限制网络互访&#x…

Vue:watchEffect的作用与性质

目录 一.watchEffect的作用 二.watchEffect的性质 三. watch对比watchEffect 四.watchEffect的使用 在 Vue 中&#xff0c;watchEffect 是一个用于副作用处理的函数&#xff0c;它是 Vue 3 Composition API 的一部分。它的主要作用是自动追踪其内部依赖的响应式状态&#x…

[机器学习]决策树

1 决策树简介 2 信息熵 3 ID3决策树 3.1 决策树构建流程 3.2 决策树案例 4 C4.5决策树 5 CART决策树&#xff08;分类&回归&#xff09; 6 泰坦尼克号生存预测案例 import pandas as pd from sklearn.model_selection import train_test_split from sklearn.tree import …

链表的快速排序(C/C++实现)

一、前言 大家在做需要排名的项目的时候&#xff0c;需要把各种数据从高到低排序。如果用的快速排序的话&#xff0c;处理数组是十分简单的。因为数组的存储空间的连续的&#xff0c;可以通过下标就可以简单的实现。但如果是链表的话&#xff0c;内存地址是随机分配的&#xf…

【H2O2|全栈】关于CSS(2)CSS基础(二)

目录 CSS基础知识 前言 准备工作 选择器的组合 盒模型 示例网页代码 后代选择器 亲代选择器 相邻兄弟选择器 后续兄弟选择器 多个元素选择器 通配符选择器 优先级 其他应用 伪类 锚链接的属性 列表的属性 list-style-type list-style-position list-style…

react 事件处理

概述 Web应用中&#xff0c;事件处理是重要的一环&#xff0c;事件处理将用户的操作行为转换为相应的逻辑执行或界面更新。在React中&#xff0c;处理事件响应的方式有多种&#xff0c;本文将详细介绍每一种处理方式的用法、使用场景和优缺点。 如果原生DOM有一个监听事件&…

QGis二次开发 —— 3、程序加载栅格tif与矢量shp文件可进行切换控制,可进行导出/导入工程(附源码)

效果 功能说明 软件可同时加载.tif栅格图片与.shp矢量图片、加载图片后可进行自由切换查看图层、可对加载的图片进行关闭 关闭后清空图层、可对加载的图片进行导出.qgs的QGIS工程、可对.qgs的QGis工程导入并导入后可进行自由切换查看图层。 源码 注意: 在加载tif栅格文件后会在…

C语言野指针

什么是野指针 野指针&#xff08;Wild Pointer&#xff09;在C语言中指的是未初始化的指针&#xff0c;即它没有被显式地指向任何有效的内存地址。使用野指针可能会导致程序访问到非法或未知的内存区域&#xff0c;从而引发不可预测的行为和错误。 为了避免出现野指针问题&am…

动态ip切换过快,会引起我的账号下次登录异常吗

在网络世界中&#xff0c;动态IP地址的使用为用户提供了灵活性和隐私保护。然而&#xff0c;频繁且快速地切换IP地址可能会引起一些安全问题&#xff0c;尤其是在涉及到账号登录时。本文将探讨动态IP切换过快是否会导致账号登录异常&#xff0c;以及如何平衡IP切换的速度与账号…

Error: ENOENT: no such file or directory, uv_cwd

鸿蒙 Harmony 的工程在进行构建的时候遇到这个问题&#xff1a;Error: ENOENT: no such file or directory, uv_cwd 详细报错其实是在 node 里面&#xff0c;因此在网络上主要有以下几种解决方式 如果是在终端运行的话&#xff0c;可以重启终端&#xff0c;看是否解决暴力终止…

el-table 如何实现行列转置?

在某些需求里需要用到 行列转置 的表格&#xff0c;但 el-table 提供的基本表格是不支持行列转置的&#xff0c;这样就需要对这个表格进行二次开发。下面来看具体实现的效果&#xff1a; 具体实现方式 基本原理就是对原有的可渲染的数据结构进行处理&#xff0c;表头与表格数…

计算机的错误计算(九十三)

摘要 探讨 log(y,x) 即以 x 为底 y 的对数的计算精度问题。 Log(y,x)运算是指 x 为底 y 的对数。 例1. 计算 log(123667.888, 0.999999999999999) . 不妨在Python中计算&#xff0c;则有&#xff1a; 若在 Excel 单元格中计算&#xff0c;则有几乎同样的输出&#xff1a; 然…

模型部署基础

神经网络的模型部署是将训练好的神经网络模型应用到实际系统中&#xff0c;以实现预测、分类、推荐等任务的过程。下图展示了模型从训练到部署的整个流程&#xff1a; 1.模型部署的平台 在线服务器端部署 在线服务器端部署适用于处理大模型、需要精度优先的应用场景&#xff…

CSCC2024数据库内核赛道Profile记录

同学参加CSCC2024数据库系统赛道比赛&#xff0c;我和他一起研究了一些优化的case&#xff0c;最后成功拿到全国2/325。在这里记录一下我们讨论优化过的问题&#xff08;建议把源码下下来边读边搜代码&#xff0c;否则会晕&#xff09; 行锁占用内存过大 Q&#xff1a;TPCC测…

liunx 计划任务

任务脚本 #!/bin/bash# 配置项 # Oracle 安装路径&#xff0c;根据实际情况修改&#xff0c;查看安装地址&#xff1a;cat /etc/oratab ORACLE_HOME/home/database/oracle/product/11.2.0 # Oracle 实例名&#xff0c;根据实际情况修改 ORACLE_SID # 数据库用户名 USER # 数据…

OpenCV运动分析和目标跟踪(1)累积操作函数accumulate()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将一个图像添加到累积图像中。 该函数将 src 或其部分元素添加到 dst 中&#xff1a; dst ( x , y ) ← dst ( x , y ) src ( x , y ) if mask…

网络基础,协议,OSI分层,TCP/IP模型

网络的产生是数据交流的必然趋势&#xff0c;计算机之间的独立的个体&#xff0c;想要进行数据交互&#xff0c;一开始是使用磁盘进行数据拷贝&#xff0c;可是这样的数据拷贝效率很低&#xff0c;于是网络交互便出现了&#xff1b; 1.网络是什么 网络&#xff0c;顾名思义是…

使用Serilog在.NET应用程序中写日志文件

在开发.NET应用程序时&#xff0c;良好的日志系统是至关重要的。它可以帮助我们跟踪应用程序的运行情况&#xff0c;更好地理解应用程序的行为&#xff0c;以及在出现问题时进行调试。今天&#xff0c;我要介绍的是一个强大且易于使用的日志库——Serilog。 什么是Serilog&…

串口接收不到数据之电阻虚焊bug分析思路

单片机和EC移远通信模块进行通信&#xff0c;相同的代码运行在相同的硬件上&#xff0c;但是一个能联网&#xff0c;一个因为没有EC的应答连不上网。 开始分析&#xff0c;排除软件问题&#xff0c;给EC模块发为什么没应答&#xff1f; 1.发送失败 2.接收失败 排除情况2&#x…

汽车租赁系统1.0版本

汽车租赁系统1.0版本比较简陋&#xff0c;以后还会有2.0、3.0……就像《我爱发明》里面的一代机器二代机器&#xff0c;三代机器一样&#xff0c;是一个迭代更新的过程&#xff08;最近比较忙&#xff0c;可能会很久&#xff09;&#xff0c;这个1.0版本很简陋&#xff0c;也请…