C语言代码实现构造大根堆

时间: 2023-02-10 08:31:20 浏览: 45
构造大根堆是堆排序的一个重要步骤。在构造大根堆时,需要保证堆中每一个父节点的值都大于它的子节点。 下面是一个 C 语言实现的构造大根堆的代码示例: ``` #include <stdio.h> void max_heapify(int *arr, int start, int end) { // 建立父节点指标和子节点指标 int dad = start; int son = dad * 2 + 1; while (son <= end) { // 如果子节点指标在范围内才做比较 if (son + 1 <= end && arr[son] < arr[son + 1]) // 先比较两个子节点大小,选择最大的 son++; if (arr[dad] > arr[son]) // 如果父节点大於子节点代表调整完毕,直接跳出函数 return; else { // 否则交换父子内容再继续子节点和孙节点比较 int temp = arr[dad]; arr[dad] = arr[son]; arr[son] = temp; dad = son; son = dad * 2 + 1; } } } void heap_sort(int *arr, int len) { // 初始化,i 从最後一个父节点开始调整 for (int i = len / 2 - 1; i >= 0; i--) max_heapify(arr, i, len - 1); // 全部交换完毕后,最后的结点就是最大的 for (int i = len - 1; i > 0; i--) { int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; max_heapify(arr, 0, i - 1); } } int main() { int arr[] = {3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4

相关推荐

// 定义一个大根堆类 class MaxHeap { private: vector<int> heap; // 使用 vector 存储堆 int size; // 堆的大小 // 工具函数 —— 交换堆中的两个元素 void swap(int& a, int& b) { int temp = a; a = b; b = temp; } // 工具函数 —— 堆化某一个节点 void heapify(int index) { int largest = index; // 先将当前节点标记为最大值 int left = index * 2 + 1; // 左孩子节点的索引 int right = index * 2 + 2; // 右孩子节点的索引 // 比较当前节点、左孩子节点和右孩子节点中的最大值 if (left < size && heap[left] > heap[largest]) { largest = left; } if (right < size && heap[right] > heap[largest]) { largest = right; } // 如果当前节点的值不是最大值,则将当前节点和最大值节点交换,并递归地对最大值节点进行堆化 if (largest != index) { swap(heap[index], heap[largest]); heapify(largest); } } public: // 构造函数 —— 建立一个空堆 MaxHeap() { size = 0; } // 获取堆中元素的数量 int getSize() { return size; } // 判断堆是否为空 bool isEmpty() { return size == 0; } // 在堆末尾添加一个元素,并将其上移对其进行调整 void add(int element) { heap.push_back(element); size++; int index = size - 1; int parent = (index - 1) / 2; while (index > 0 && heap[index] > heap[parent]) { swap(heap[index], heap[parent]); index = parent; parent = (index - 1) / 2; } } // 获取堆顶元素 int peek() { if (size == 0) { throw "Heap is empty."; } return heap[0]; } // 删除堆顶元素,并将堆末尾的元素放到堆顶,然后将其下沉进行调整 int remove() { if (size == 0) { throw "Heap is empty."; } int root = heap[0]; heap[0] = heap[size - 1]; size--; heap.pop_back(); heapify(0); return root; } };
1. 树状大根堆 树状大根堆是一种二叉树,满足以下性质: 1. 每个节点的值都大于等于其子节点的值。 2. 树的最后一层节点都靠左排列。 在Python中,我们可以使用列表来表示二叉树,其中第i个元素的左子节点为2i,右子节点为2i+1,父节点为i//2。 以下是创建树状大根堆的代码: python class MaxHeap: def __init__(self, arr=None): self.heap = [0] if arr: self.heap.extend(arr) self._build_heap() def _build_heap(self): n = len(self.heap) - 1 for i in range(n // 2, 0, -1): self._heapify(i) def _heapify(self, i): n = len(self.heap) - 1 largest = i left = 2 * i right = 2 * i + 1 if left <= n and self.heap[left] > self.heap[largest]: largest = left if right <= n and self.heap[right] > self.heap[largest]: largest = right if largest != i: self.heap[i], self.heap[largest] = self.heap[largest], self.heap[i] self._heapify(largest) def push(self, val): self.heap.append(val) i = len(self.heap) - 1 while i > 1 and self.heap[i] > self.heap[i // 2]: self.heap[i], self.heap[i // 2] = self.heap[i // 2], self.heap[i] i //= 2 def pop(self): if len(self.heap) == 1: return None if len(self.heap) == 2: return self.heap.pop() root = self.heap[1] self.heap[1] = self.heap.pop() self._heapify(1) return root 2. 堆排序 堆排序是一种排序算法,基于树状大根堆实现。其思路是先将数组构建成树状大根堆,然后将堆顶元素与最后一个元素交换,再将前面的元素重新构建成树状大根堆,重复此过程直到数组有序。 以下是堆排序的代码: python def heap_sort(arr): n = len(arr) heap = [0] + arr for i in range(n // 2, 0, -1): _heapify(heap, i, n) for i in range(n, 0, -1): heap[1], heap[i] = heap[i], heap[1] _heapify(heap, 1, i - 1) return heap[1:] def _heapify(heap, i, n): largest = i left = 2 * i right = 2 * i + 1 if left <= n and heap[left] > heap[largest]: largest = left if right <= n and heap[right] > heap[largest]: largest = right if largest != i: heap[i], heap[largest] = heap[largest], heap[i] _heapify(heap, largest, n) 3. 取前k个值 在树状大根堆中,堆顶元素是最大的元素,可以通过不断取出堆顶元素来获得最大的k个元素。 以下是取前k个值的代码: python def top_k(arr, k): n = len(arr) heap = [0] + arr[:k] for i in range(k // 2, 0, -1): _heapify(heap, i, k) for i in range(k, n): if arr[i] > heap[1]: heap[1] = arr[i] _heapify(heap, 1, k) return heap[1:] 以上是树状大根堆、堆排序和取前k个值的Python实现。
Java堆排序的实现步骤如下: 1. 将待排序数组构建成一个大根堆(或小根堆)。 2. 将堆顶元素与堆底元素交换位置,并将堆底元素移出堆。 3. 对新的堆顶元素进行堆调整,使其满足堆的性质。 4. 重复步骤2和3,直到堆中只剩下一个元素。 Java代码实现如下: java public class HeapSort { public static void heapSort(int[] arr) { if (arr == null || arr.length < 2) { return; } // 构建大根堆 for (int i = arr.length / 2 - 1; i >= 0; i--) { heapify(arr, i, arr.length); } // 将堆顶元素与堆底元素交换位置,并将堆底元素移出堆。对新的堆顶元素进行堆调整,使其满足堆的性质。 for (int i = arr.length - 1; i > 0; i--) { swap(arr, 0, i); heapify(arr, 0, i); } } private static void heapify(int[] arr, int index, int size) { int left = index * 2 + 1; int right = index * 2 + 2; int largest = index; if (left < size && arr[left] > arr[largest]) { largest = left; } if (right < size && arr[right] > arr[largest]) { largest = right; } if (largest != index) { swap(arr, index, largest); heapify(arr, largest, size); } } private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } 在该代码中,heapify方法用于将一个节点调整为符合堆性质的节点,swap方法用于交换两个元素的位置。在heapSort方法中,首先构建一个大根堆,然后依次将堆顶元素与堆底元素交换位置,并对新的堆顶元素进行堆调整,直到堆中只剩下一个元素。
在PriorityQueue类中,可以通过传入一个比较器来定义大根堆。具体的写法是在new PriorityQueue<>的参数部分加入比较器,比如(v1, v2) -> v2 - v1。这样定义的PriorityQueue对象就会按照降序排列元素,即最大的元素会被放在队列的前面。例如,可以使用以下代码定义一个大根堆的PriorityQueue对象: PriorityQueue<Integer> queue = new PriorityQueue<>((v1, v2) -> v2 - v1); 这样,当向队列中添加元素时,会按照降序的方式进行排序,最大的元素会被放在队列的前面。 #### 引用[.reference_title] - *1* [PriorityQueue实现大根堆和小根堆](https://blog.csdn.net/lwycc2333/article/details/104196362)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [优先队列PriorityQueue (大根堆/小根堆/TopK问题)](https://blog.csdn.net/weixin_61543601/article/details/125003015)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Java 如何用 PriorityQueue 实现大根堆?](https://blog.csdn.net/qq_38522564/article/details/115029671)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

最新推荐

基于51单片机的usb键盘设计与实现(1).doc

基于51单片机的usb键盘设计与实现(1).doc

"海洋环境知识提取与表示:专用导航应用体系结构建模"

对海洋环境知识提取和表示的贡献引用此版本:迪厄多娜·察查。对海洋环境知识提取和表示的贡献:提出了一个专门用于导航应用的体系结构。建模和模拟。西布列塔尼大学-布雷斯特,2014年。法语。NNT:2014BRES0118。电话:02148222HAL ID:电话:02148222https://theses.hal.science/tel-02148222提交日期:2019年HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire论文/西布列塔尼大学由布列塔尼欧洲大学盖章要获得标题西布列塔尼大学博士(博士)专业:计算机科学海洋科学博士学院对海洋环境知识的提取和表示的贡献体系结构的建议专用于应用程序导航。提交人迪厄多内·察察在联合研究单位编制(EA编号3634)海军学院

react中antd组件库里有个 rangepicker 我需要默认显示的当前月1号到最后一号的数据 要求选择不同月的时候 开始时间为一号 结束时间为选定的那个月的最后一号

你可以使用 RangePicker 的 defaultValue 属性来设置默认值。具体来说,你可以使用 moment.js 库来获取当前月份和最后一天的日期,然后将它们设置为 RangePicker 的 defaultValue。当用户选择不同的月份时,你可以在 onChange 回调中获取用户选择的月份,然后使用 moment.js 计算出该月份的第一天和最后一天,更新 RangePicker 的 value 属性。 以下是示例代码: ```jsx import { useState } from 'react'; import { DatePicker } from 'antd';

基于plc的楼宇恒压供水系统学位论文.doc

基于plc的楼宇恒压供水系统学位论文.doc

"用于对齐和识别的3D模型计算机视觉与模式识别"

表示用于对齐和识别的3D模型马蒂厄·奥布里引用此版本:马蒂厄·奥布里表示用于对齐和识别的3D模型计算机视觉与模式识别[cs.CV].巴黎高等师范学校,2015年。英语NNT:2015ENSU0006。电话:01160300v2HAL Id:tel-01160300https://theses.hal.science/tel-01160300v22018年4月11日提交HAL是一个多学科的开放获取档案馆,用于存放和传播科学研究文件,无论它们是否已这些文件可能来自法国或国外的教学和研究机构,或来自公共或私人研究中心。L’archive ouverte pluridisciplinaire博士之路博士之路博士之路在获得等级时,DOCTEURDE L'ÉCOLE NORMALE SUPERIEURE博士学校ED 386:巴黎中心数学科学Discipline ou spécialité:InformatiquePrésentée et soutenue par:马蒂厄·奥布里le8 may 2015滴度表示用于对齐和识别的Unité derechercheThèse dirigée par陪审团成员équipe WILLOW(CNRS/ENS/INRIA UMR 8548)慕尼黑工业大学(TU Munich�

valueError: Pandas data cast to numpy dtype of object. Check input data with np.asarray(data).

这个错误通常发生在使用 Pandas DataFrame 时,其中包含了一些不能被转换为数字类型的数据。 解决方法是使用 `pd.to_numeric()` 函数将数据转换为数字类型。例如: ```python import pandas as pd import numpy as np # 创建一个包含字符串和数字的 DataFrame df = pd.DataFrame({'A': ['a', 'b', 'c'], 'B': [1, 2, '3']}) # 尝试将整个 DataFrame 转换为数字类型会报错 np.asarray(df, dtype=np.float) # 使

基于VC--的五子棋程序设计与实现毕业设计.doc

基于VC--的五子棋程序设计与实现毕业设计.doc

体系结构驱动的普遍性应用程序中

体系结构驱动的普遍性应用程序的自主适应艾蒂安·甘德里勒引用此版本:艾蒂安·甘德里勒。由体系结构驱动的普遍性应用程序的自主适应。无处不在的计算。格勒诺布尔大学,2014年。法语。NNT:2014GRENM078。电话:01215004HAL ID:电话:01215004https://theses.hal.science/tel-01215004提交日期:2015年HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire论文要获得的等级格勒诺布尔大学博士专业:计算机科学部长令:2006年提交人艾蒂安·G·安德里尔论文由Philippe LAlanda指导由Stephanie CHollet共同指导在格勒诺布尔计算机科学实验室编写数学、信息科学与技术、计算机科学博士体系结构驱动的普遍性应用程序的自主适应论文�

STM32F103 RCT6 LCD显示正弦波并且设置可以调节振幅的触摸按键代码

以下是基于STM32F103RCT6和Keil MDK-ARM开发环境的LCD显示正弦波并且设置可以调节振幅的触摸按键代码: ```c #include "stm32f10x.h" #include "lcd.h" //LCD驱动库 #include "math.h" //数学库 #define PI 3.14159 //圆周率 void delay_ms(uint16_t n); int main(void) { float amplitude = 20; //振幅 float frequency = 1; //频率 float phase = 0; //相位

我国软件和信息技术服务业的发展现状及存在的问题.pdf

我国软件和信息技术服务业的发展现状及存在的问题.pdf