news 2026/8/3 5:49:23

Linux环境下的C语言编程(四十二)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux环境下的C语言编程(四十二)

一、优先队列概念

优先队列是一种特殊的队列,元素出队顺序不是FIFO,而是按照优先级

  • 每次出队的是优先级最高(或最低)的元素

二、两种实现方式对比

特性使用数组/链表(朴素实现)使用堆(推荐实现)
入队时间复杂度O(1)O(log n)
出队(获取最高优先级)时间复杂度O(n)O(log n)
查找最高优先级O(n)O(1)

三、数组实现

1. 数组无序实现

#include <stdio.h> #include <stdlib.h> #include <limits.h> #define MAX_SIZE 100 typedef struct { int data[MAX_SIZE]; int size; } PriorityQueueArray; // 初始化 void initPriorityQueueArray(PriorityQueueArray* pq) { pq->size = 0; } // 入队 O(1) - 直接添加到尾部 void enqueueArray(PriorityQueueArray* pq, int value) { if (pq->size >= MAX_SIZE) { printf("队列已满!\n"); return; } pq->data[pq->size++] = value; } // 出队 O(n) - 需要遍历找到最大值 int dequeueArray(PriorityQueueArray* pq) { if (pq->size == 0) { printf("队列为空!\n"); return INT_MIN; } // 找到最大值的索引 int maxIndex = 0; for (int i = 1; i < pq->size; i++) { if (pq->data[i] > pq->data[maxIndex]) { maxIndex = i; } } // 保存最大值 int maxValue = pq->data[maxIndex]; // 用最后一个元素填补空缺 pq->data[maxIndex] = pq->data[pq->size - 1]; pq->size--; return maxValue; } // 查看最高优先级 O(n) int peekArray(PriorityQueueArray* pq) { if (pq->size == 0) return INT_MIN; int maxValue = pq->data[0]; for (int i = 1; i < pq->size; i++) { if (pq->data[i] > maxValue) { maxValue = pq->data[i]; } } return maxValue; } 2. 数组有序

四、堆实现

是一种特殊的完全二叉树,满足:

  • 最大堆:父节点 ≥ 子节点

  • 最小堆:父节点 ≤ 子节点

1. 最大堆实现优先队列

#include <stdio.h> #include <stdlib.h> #include <limits.h> #define MAX_HEAP_SIZE 100 typedef struct { int data[MAX_HEAP_SIZE]; int size; } MaxHeap; // 辅助函数:交换两个元素 void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // 初始化堆 void initMaxHeap(MaxHeap* heap) { heap->size = 0; } // 获取父节点索引 int parent(int i) { return (i - 1) / 2; } // 获取左孩子索引 int leftChild(int i) { return 2 * i + 1; } // 获取右孩子索引 int rightChild(int i) { return 2 * i + 2; } // 上浮操作(维护堆性质)O(log n) void heapifyUp(MaxHeap* heap, int index) { while (index > 0 && heap->data[parent(index)] < heap->data[index]) { swap(&heap->data[parent(index)], &heap->data[index]); index = parent(index); } } // 下沉操作(维护堆性质)O(log n) void heapifyDown(MaxHeap* heap, int index) { int maxIndex = index; int left = leftChild(index); int right = rightChild(index); // 找到当前节点、左孩子、右孩子中的最大值 if (left < heap->size && heap->data[left] > heap->data[maxIndex]) { maxIndex = left; } if (right < heap->size && heap->data[right] > heap->data[maxIndex]) { maxIndex = right; } // 如果当前节点不是最大值,交换并继续下沉 if (index != maxIndex) { swap(&heap->data[index], &heap->data[maxIndex]); heapifyDown(heap, maxIndex); } } // 入队操作 O(log n) void heapEnqueue(MaxHeap* heap, int value) { if (heap->size >= MAX_HEAP_SIZE) { printf("堆已满!\n"); return; } // 1. 将新元素放到末尾 heap->data[heap->size] = value; heap->size++; // 2. 上浮调整 heapifyUp(heap, heap->size - 1); } // 出队操作 O(log n) int heapDequeue(MaxHeap* heap) { if (heap->size == 0) { printf("堆为空!\n"); return INT_MIN; } // 1. 保存堆顶(最大值) int maxValue = heap->data[0]; // 2. 用最后一个元素替换堆顶 heap->data[0] = heap->data[heap->size - 1]; heap->size--; // 3. 下沉调整 heapifyDown(heap, 0); return maxValue; } // 查看堆顶元素 O(1) int heapPeek(MaxHeap* heap) { if (heap->size == 0) return INT_MIN; return heap->data[0]; } // 构建堆 O(n) - 弗洛伊德建堆法 void buildHeap(MaxHeap* heap, int arr[], int n) { // 复制数据 for (int i = 0; i < n; i++) { heap->data[i] = arr[i]; } heap->size = n; // 从最后一个非叶子节点开始下沉 for (int i = n / 2 - 1; i >= 0; i--) { heapifyDown(heap, i); } } // 打印堆(树状结构) void printHeapTree(MaxHeap* heap, int index, int level) { if (index >= heap->size) return; // 先打印右子树 printHeapTree(heap, rightChild(index), level + 1); // 打印当前节点 for (int i = 0; i < level; i++) printf(" "); printf("%d\n", heap->data[index]); // 打印左子树 printHeapTree(heap, leftChild(index), level + 1); }

2. 最小堆实现

typedef struct { int data[MAX_HEAP_SIZE]; int size; } MinHeap; // 最小堆的上浮操作 void minHeapifyUp(MinHeap* heap, int index) { while (index > 0 && heap->data[parent(index)] > heap->data[index]) { swap(&heap->data[parent(index)], &heap->data[index]); index = parent(index); } } // 最小堆的下沉操作 void minHeapifyDown(MinHeap* heap, int index) { int minIndex = index; int left = leftChild(index); int right = rightChild(index); if (left < heap->size && heap->data[left] < heap->data[minIndex]) { minIndex = left; } if (right < heap->size && heap->data[right] < heap->data[minIndex]) { minIndex = right; } if (index != minIndex) { swap(&heap->data[index], &heap->data[minIndex]); minHeapifyDown(heap, minIndex); } }

五、时间复杂度对比分析

各种实现的时间复杂度:

操作无序数组/链表有序数组
插入(入队)O(1)O(n)O(log n)
删除最大(出队)O(n)O(1)O(log n)
获取最大(查看)O(n)O(1)O(1)
构建O(1)O(n log n)O(n)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/2 8:45:14

计算机毕业设计springboot家政服务管理系统 基于SpringBoot的智慧家政服务平台的设计与实现 面向社区的Java家政服务预约与评价系统

计算机毕业设计springboot家政服务管理系统o8z7q6qn &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。快节奏的城市生活让“把家务交给专业的人”成为刚需&#xff0c;可传统中介模…

作者头像 李华
网站建设 2026/8/2 16:40:48

SSDTTime终极指南:5步搞定ACPI热补丁生成

想要彻底解决Hackintosh硬件兼容性难题&#xff1f;SSDTTime作为一款跨平台ACPI热补丁生成工具&#xff0c;能够自动化创建各类SSDT和DSDT补丁&#xff0c;让你的黑苹果系统运行如丝般顺滑。本文将为你揭示这款工具的完整使用方法&#xff01; 【免费下载链接】SSDTTime SSDT/D…

作者头像 李华
网站建设 2026/8/3 5:33:03

2026年AI面试布局:破解规模化招聘的效率困局

校招季一天收到5000份简历&#xff0c;却只能安排30场面试&#xff1f;传统招聘模式已无法应对高并发、高成本、低体验的三重压力。2026年&#xff0c;企业必须重新思考AI面试的战略价值。 一、企业大规模招聘的困境 场景化痛点直击HR日常&#xff1a; 人力瓶颈&#xff1a;…

作者头像 李华
网站建设 2026/8/2 8:49:45

当开题报告成为科研长征的“第一道关卡”,Paperzz的AI开题报告功能是如何把“选题迷茫”变成“逻辑闭环”的

Paperzz-AI官网免费论文查重复率AIGC检测/开题报告/文献综述/论文初稿 paperzz - 开题报告https://www.paperzz.cc/proposal 前言&#xff1a;在导师的“灵魂拷问”面前&#xff0c;我点开了那个橙色按钮 “研究问题不聚焦。” “理论基础薄弱&#xff0c;缺乏文献支撑。” “…

作者头像 李华
网站建设 2026/8/2 8:22:20

2、黑客必备:Kali Linux 安装与基础入门

黑客必备:Kali Linux 安装与基础入门 一、Kali Linux 简介与下载 1.1 未来趋势与选择 从市场占比来看,Microsoft Windows 在移动设备市场仅占 7%,而 Unix/Linux 才是未来趋势。对于想要进入黑客领域的人来说,选择合适的操作系统至关重要,Kali Linux 就是不错的选择。 …

作者头像 李华