news 2026/5/1 8:53:48

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/5/1 8:38:18

免费解决Nintendo Switch启动失败的7种终极方法

免费解决Nintendo Switch启动失败的7种终极方法 【免费下载链接】Atmosphere Atmosphre is a work-in-progress customized firmware for the Nintendo Switch. 项目地址: https://gitcode.com/GitHub_Trending/at/Atmosphere Atmosphere自定义固件为Nintendo Switch带来…

作者头像 李华
网站建设 2026/5/1 0:54:00

Monitorian终极指南:Windows多显示器亮度调节神器

Monitorian终极指南&#xff1a;Windows多显示器亮度调节神器 【免费下载链接】Monitorian A Windows desktop tool to adjust the brightness of multiple monitors with ease 项目地址: https://gitcode.com/gh_mirrors/mo/Monitorian 想要轻松调节Windows系统中多个显…

作者头像 李华
网站建设 2026/5/1 7:19:16

Tauri + WebAssembly + Rust:桌面应用性能飞跃终极指南

还在为JavaScript性能瓶颈而烦恼&#xff1f;想要构建既轻量又强大的桌面应用&#xff1f;Tauri框架与WebAssembly的结合&#xff0c;正在重新定义桌面开发的性能标准&#xff01;&#x1f680; 【免费下载链接】tauri Build smaller, faster, and more secure desktop applica…

作者头像 李华
网站建设 2026/4/27 6:49:03

DREAM3D完整教程:材料科学3D微结构重建与分析的终极指南

DREAM3D完整教程&#xff1a;材料科学3D微结构重建与分析的终极指南 【免费下载链接】DREAM3D Data Analysis program and framework for materials science data analytics, based on the managing framework SIMPL framework. 项目地址: https://gitcode.com/gh_mirrors/dr…

作者头像 李华
网站建设 2026/4/29 0:49:50

0.8秒修复1080P视频:字节跳动SeedVR2-3B重构行业效率标准

0.8秒修复1080P视频&#xff1a;字节跳动SeedVR2-3B重构行业效率标准 【免费下载链接】SeedVR2-3B 项目地址: https://ai.gitcode.com/hf_mirrors/ByteDance-Seed/SeedVR2-3B 导语 字节跳动开源的SeedVR2-3B模型通过一步式扩散对抗后训练技术&#xff0c;将1080P视频修…

作者头像 李华