(二叉)堆操作

C++STL堆操作 C++STL堆操作并没有什么用的更新时间定义原因某玄学方法 并没有什么用的更新时间 【2019/02/21】 17:55 第一次更新(疑似更完) 定义 优先队列 需要调动到#include<queue>,以下以a为例: 大根堆的调用:priority_queue<int>a; 小根堆的调用:priority_queue<int,vector<int&amp 阅读详情

堆操作

实验目的

(一)建堆:将数组A[1..n]变成一个最大堆。

(二)堆排序:将一个堆中的元素按递减排序输出。

(三)用插入方法建堆:堆大小从1到n每次插入一个元素到堆中,直到n个元素入堆。

 

实验原理

(二叉)堆是一个数组,它可以被看成一个近似的完全二叉树。树上的每一个结点对应数组中的一个元素。除了最底层外,该树是完全充满的,而且是从左向右填充。表示堆的数组A包括两个属性:A.length(通常)给出数组元素的个数,A.heap-size表示有多少个堆元素存储在该数组中。也就是说,虽然A[1..A.length]可能都存有数据,但是只有A[1..A.heap-size]中存放的是堆的有效元素,这个,0 <=A.heap-size <= A.length 。树的根节点是A[1]。

二叉堆可以分为两种形式:最大堆和最小堆。在这两种堆中,结点的值都要满足堆的性质,但一些细节定义则有所差异。在最大堆中,最大堆性质是指除了根以外的所有结点i都要满足:A[PARENT(i)] >= A[i] ,也就是说,某个结点的值至多与其父结点一样大。因此,堆中的最大元素存放在根结点中;并且,在任一子树中,该子树所包含的所有结点的值都不大于该子树根节点的值。最小堆的组织方式正好相反:最小堆性质是指除了根以外的所有结点i都有A[PARENT(i)] <= A[i] ,最小堆中的最小元素存放在根结点中。

 

实验过程

(一)维护堆的性质

MAX-HEAPIFY是用于维护最大堆性质的重要过程。它的输入为一个数组A和一个下标i。在调用MAX-HEAPIFY的时候,对于违背了最大堆的性质的A[i]使其在最大堆中“逐级下降”,从而使得以下标i为根结点的子树重新遵循最大堆的性质。

MAX-HEAPIFY(A, i)

1 l = LEFT(i)

2 r = RIGHT(i)

3 if l <= A.heap-size andA[l] > A[i]

4     largest = l

5 else largest = i

6 if r <= A.heap-size andA[r] > A[largest]

7     largest = r

8 if largest != i

9     exchange A[i] with A[largest]

10    MAX-HEAPIFY(A, largest)

 

(二)建堆

我们可以用自底向上的方法利用过程MAX-HEAPIFY把一个大小为n = A.length的数组A[1..n]转换为最大堆。子数组A(|n/2|+1..n)中的元素都是树的叶节点。对每一个叶节点都调用MAX-HEAPIFY进行调整,从而满足最大堆的性质。

BUILD-MAX-HEAP

1 A.heap-size = A.length

2 for i = |A.length/2| downto1

3     MAX-HEAPIFY(A, i)

 


(三)堆排序

由于数组中的最大元素总是在根结点A[1]中,通过把它与A[n]进行互换,我们可以让该元素放到正确的位置。这个时候,我们从堆中去掉结点n(即通过减少A.heap-size的值来实现),剩余的节点中,原来根的孩子仍然是最大堆,而新的节点可能违背最大堆的性质,为了维护最大堆的性质,调用一次MAX-HEAPIFY(A, 1),从而在A[1..n-1]上构造一个新的最大堆。

HEAPSORT(A)

1 BUILD-MAX-HEAP(A)

2 for i = A.length downto 2

3     exchange A[1] with A[i]

4     A.heap-size = A.heap-size - 1

5     MAX-HEAPIFY(A, 1)

 

(四)插入方法建堆

MAX-HEAP-INSERT能够实现INSERT操作。它的输入是要被插入到最大堆A中的新元素的关键字。MAX-HEAP-INSERT首先通过增加一个关键字为-∞的叶节点来扩展最大堆,然后调用HEAP-INCREASE-KEY为新节点设置对应的关键字,同时保持最大堆的性质。

MAX-HEAP-INSERT(A, key)

1 A.heap-size = A.heap-size +1

2 A[A.heap-size] = -∞

3 HEAP-INCREASE-KEY(A,A.heap-size, key)

 

HEAP-INCREASE-KEY(A, i, key)

1 if key < A[i]

2     error“new key is smaller than current key”

3 A[i] = key

4 while i > 1 and A[PARENT(i)]< A[i]

5     exchange A[i] with A[PARENT(i)]

6     i = PARENT(i)

 

实验总结

(一)将整个实验过程完成后,深入理解了二叉堆的性质。堆的优点:在大多数计算机上,在实现PARENT(i),LEFT(i),RIGHT(i)过程中,可以通过较少的指令(左移,右移)进行计算。

(二)在建堆的过程中,有一个巧妙的地方:就是对于A[|A.length/2|..1]的叶节点进行最大堆的性质维护,而不是遍历整个堆。

(三)堆排序的实际应用场景:基于最大堆实现最大优先队列(记录将要执行的各个作业以及它们之间的相对优先级),从而应用到计算机系统的作业调度中。

 

附录(代码)

(一)建堆

#include <stdio.h>

#include <stdlib.h>

 

#define a_length 10

 

int a_heap_size;

 

void max_heapify(int a[], int i){

    intl,r,largest;

    int change;

    l = 2 * i +1;

    r = 2 * i +2;

    if(l <=a_heap_size-1 && a[l] > a[i])

       largest =l;

    else largest= i;

    if(r <=a_heap_size-1 && a[r] > a[largest])

       largest =r;

    if(largest !=i){

       change     = a[i];

       a[i]       = a[largest];

       a[largest]= change;

       max_heapify(a,largest);

    }     

}

 

void build_max_heap(int a[]){

    int i;

    a_heap_size =a_length;

    for(i =a_length/2 - 1; i >= 0; i--)

       max_heapify(a,i);

}

 

int main(){

    inta[a_length] = {4,1,3,2,16,9,10,14,8,7};

    int i;

 

    printf("origin_heapa[]=");

    for(i = 0; i< 10; i++)

       printf("%d  ",a[i]);

    printf("\n");

   

    build_max_heap(a);

 

    printf("  max_heap a[]=");

    for(i = 0; i< 10; i++)

       printf("%d  ",a[i]);

    printf("\n");

}

 

 

 

(二)堆排序

#include <stdio.h>

#include <stdlib.h>

 

#define a_length 10

 

int a_heap_size;

 

void max_heapify(int a[], int i){

    intl,r,largest;

    int change;

    l = 2 * i +1;

    r = 2 * i +2;

    if(l <=a_heap_size-1 && a[l] > a[i])

       largest =l;

    else largest= i;

    if(r <=a_heap_size-1 && a[r] > a[largest])

       largest =r;

    if(largest !=i){

       change     = a[i];

       a[i]       = a[largest];

       a[largest]= change;

       max_heapify(a,largest);

    }     

}

 

void build_max_heap(int a[]){

    int i,j;

    a_heap_size =a_length;

    for(i =a_length/2 - 1; i >= 0; i--)

       max_heapify(a,i);

}

 

void heapsort(int a[]){

    inti,exchange;

    int j;

    for(i =a_length-1; i >= 1; i--){

       exchange    = a[0];

       a[0]        = a[i];

       a[i]        = exchange;

       a_heap_size= a_heap_size - 1;

      

       max_heapify(a,0);

 

       printf("\na_heap_size= %d   i = %d  \n",a_heap_size,i);

       for(j = 0;j < 10; j++)

           printf("%d  ",a[j]);

       printf("\n");

 

    }

}

 

 

int main(){

    int a[a_length] = {4,1,3,2,16,9,10,14,8,7};

    int i;

 

    printf("origin_heapa[]=");

    for(i = 0; i< 10; i++)

       printf("%d  ",a[i]);

    printf("\n");

   

    build_max_heap(a);

    printf("  max_heap a[]=");

    for(i = 0; i< 10; i++)

       printf("%d  ",a[i]);

    printf("\n");

 

    heapsort(a);

    printf("heap_sort a[]=");

    for(i = 0; i< 10; i++)

       printf("%d  ",a[i]);

    printf("\n");

}

 

 

 

(三)用插入法建堆

#include <stdio.h>

#include <stdlib.h>

 

#define a_length 10

int a_heap_size;

int insert_length;

 

int parent(int i){

    int a;

    a = (i-1)/2;

    return a;

}

 

void heap_increase_key(int a[], int i, int key){

    int exchange;

    int a_end;

    //if(key <a[i-1])

    //  printf("new key is smaller than currentkey!\n");

    a_end      = i - 1;

    a[a_end]   = key;

   

    while(a_end> 0 && a[parent(a_end)] < a[a_end]){

       exchange         = a[a_end];

       a[a_end]         = a[parent(a_end)];

       a[parent(a_end)]= exchange;

       a_end            = parent(a_end);

//     printf("\n1111111111111\n");

    }

}

 

void max_heap_insert(int a[], int key){

    a_heap_size =a_heap_size + 1;

    a[a_heap_size-1]= -1;

    heap_increase_key(a,a_heap_size, key);

}

 

void build_max_heap(int a[]){

    int i;

    a_heap_size =1;

    for(i = 1; i< insert_length; i++){

       max_heap_insert(a,a[i]);

//     printf("\n66666666666\n");

    }

}

 

int main(){

    inta[a_length];

    int number,i;

    printf("inputthe numbers:");

    scanf("%d",&number);

    //printf("\n");

    //printf("number=%d\n",number);

    insert_length= number;

   

    printf("inputthe array:");

    for(i = 0; i< number; i++)

       scanf("%d",&a[i]);

   

    printf("\n");

    for(i = 0; i <number; i++)

       printf("a[%d]=%d  ",i,a[i]);

    printf("\n");

 

    build_max_heap(a);

    printf("max_heapa[]= ");

    for(i = 0; i< number; i++)

       printf("%d  ",a[i]);

    printf("\n");

}

 

 

【数字逻辑电路课程设计】多功能数码管时钟VHDL+quartus II-EP1C12F324C8+源码+付费资源 我希望需要我这篇文章的是正常学习数字逻辑课程且正在设计数码管时钟的同学。我个人不推荐直接获取源代码,因此我另有一份付费资源是完整源代码;我推荐各位去研究我代码的逻辑尝试自己书写属于自己的代码,因此我保留了注释但隐去了变量。由于时间有限,我的设计不够完美,仍有很多缺陷,我将我的展望写在后面,各位可以尝试实现。我不为难同学,作为同学我理解各位设计的辛苦,因此如果有需要,私信我提供隐去敏感信息的学生证照片可直接获取源代码。 阅读详情

相关推荐

深入解析西门子S7通信协议:从抓包到实战应用

本文深入解析西门子S7通信协议,从环境搭建、抓包分析到实战应用,提供了一套完整的协议分析方法。通过Wireshark工具进行抓包分析,详细拆解了S7协议各层结构,并结合真实案例,展示了如何利用抓包技术解决通信故障、优化性能及进行安全审计,是掌握工业通信底层原理的实用指南。

weixin_29224529的博客 282

算法导论--第六章--堆排序

6.1 认识堆 (二叉)堆是一个数组,他可以被看成一个近似的wan

litlit023的专栏 455

C# .NET6 TesseractOCR 图片文字识别

在你的项目中的tessdata-main文件夹找到这几个文件,并右键->属性设置为【如果较新则复制】有几个需要用到的模型,需要生成的时候复制到输出目录中,在项目中设置即可。TesseractOCR兼容 x86 与 x64。附 :ImageUtils.RegionCropping()源码。Visual Studio 2022 社区版。下载完成后解压在你的项目中,如图所示。从官方项目中获取模型数据, 网址为。

qq_44121554的博客 3854

二叉堆的构建、插入、删除等操作

共享内存就是两个或者多个进程共享的一块区域。只要一个进程改变了这块地址中的内容的时候,其他进程便会察觉到改变的内容。 (1)创建共享内存 int shmget(key_t key, int size, int shmflg) (2)将共享内存映射到自己的内存空间 void* shmat(int shmid, const void* shmaddr, int shmflg) shmi...

暖心~的博客 2448

comsol移动网格_comsol模拟移动的纳秒脉冲激光烧蚀材料,温度场分布,结果总不理想,求助大佬!!...

本人comsol新手一枚,希望大家多多指点研究课题:纳秒脉冲激光刻蚀材料表面想用comsol模拟刻蚀过程中的温度场分布,脉宽为300ns,重复频率100kHz,光斑移动速度为5000mm/s,光斑直径50um,激光功率10W,材料种类为:有机涂层,属性如下目前,采用的是一个移动的高斯面光源x脉冲函数,脉冲函数我用的是一个周期性方波:周期性拓展后,画出来的脉冲图,不知道为什么在0~1s的区间内只有1...

weixin_33288893的博客 4742

使用扫频信号测量房间脉冲响应

脉冲响应的测量

liuderong0的博客 1765

堆的基本操作

目录 一、堆(heap) 1.1 基本概念 二、堆的基本操作 2.1 向最大堆中添加一个元素 2.2 取出堆中最大元素 2.3 堆化(heapify) 三、源代码 一、堆(heap) 1.1 基本概念 堆:堆在逻辑上就是一颗完全二叉树,物理上是保存在数组中。 特点: 最大堆/大根堆:堆中根节点的值大于等于子树中的节点值。 最小堆/小根堆:堆中根节点的值小于等于子树中的节点值。 在最大堆中,只能保证当前根节点大于等于子树的所有节点,但是节点的大小关系和所处的层次无关。 堆的基

m0_49991895的博客 1386

从统一入口到运营中枢:全面看懂 SAP for Me 的能力边界、使用方式与项目价值

SAP for Me 是 SAP 推出的统一工作平台,旨在整合原本分散在多个系统中的关键信息与操作。它将许可证管理、系统状态、支持工单、维护合同、产品路线图等核心功能集中到一个界面,为不同角色提供定制化视图。平台包含多个功能模块:Home 作为个性化工作台展示待办事项与风险;Calendar 整合各类维护事件与关键时间节点;Reporting 提供跨域分析与趋势洞察;Finance & Legal 管理订单、发票与合规事项;Portfolio & Products 则展示产品全景与路线图。该

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 122

【数据结构】堆的基本操作

本篇博客主要来介绍堆的基本结构和操作,其中重要的点在于堆的向上调整和向下调整的实现,这两个函数的实现是堆这个数据结构最核心的地方,也是后面我们实现堆排序和TOP-K问题的关键。

Brant_zero的博客 1379

OpenHarmony电源管理驱动架构剖析:HDI框架下的低功耗实现

鸿蒙电源管理驱动模块是OpenHarmony操作系统中负责设备电源状态管理的核心组件。该模块基于HDI(Hardware Device Interface)框架实现,提供了完整的电源管理功能,包括系统休眠/唤醒、运行锁管理、休眠模式控制等核心功能。public:// 主要接口函数// 运行锁管理private:// 内部辅助函数// 成员变量public:// 运行锁控制接口// 回调管理private:// 内部辅助函数。

m0_67505153的博客 209

PX4从放弃到精通(二十七):固定翼姿态控制

固件版本 PX4 1.13.2欢迎交流学习,可加左侧名片。

超维空间科技的博客 6889

堆的基本操作,堆排序(C语言实现)初始化,插入,删除,销毁,排序

完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。要注意的是满二叉树是一种特殊的完全二叉树。堆的性质:堆中某个节点的值总是不大于或不小于其父节点的值;堆总是一棵完全二叉树。

m0_74774759的博客 1563

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

堆的操作

编写代码,实现最小堆(Min-Heap)的操作。 输入格式: 第一行是两个不大于1000的正整数N和K,用空格间隔。其中N是堆的容量,需创建一个容量为N的堆。 接下来K行,是对这个堆的依次的K项插入或删除操作:用1 x表示插入元素x;用-1表示删除堆顶。 接下来一行是一个不大于1000的正整数M, 接下来一行是M个整数(在整型范围内),用空格间隔, 要求将这M个整数组成的列表调...

LightInDarkness的博客 2715

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

PTA 堆的操作

7-15 堆的操作 (20分) 编写代码,实现最小堆(Min-Heap)的操作。 输入格式: 第一行是两个不大于1000的正整数N和K,用空格间隔。其中N是堆的容量,需创建一个容量为N的堆。 接下来K行,是对这个堆的依次的K项插入或删除操作:用 1 x 表示插入元素x;用 -1 表示删除堆顶。 接下来一行是一个不大于1000的正整数M, 接下来一行是M个整数(在整型范围内),用空格间隔, 要求将这...

qq_43778565的博客 3575

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【堆】堆的基本概念及操作,堆与优先队列

Heap;

2401_87820834的博客 2215

堆以及堆的操作

堆 1. 定义: 堆(英语:heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。 堆总是满足下列性质: ①堆中某个节点的值总是不大于或不小于其父节点的值; ②堆总是一棵完全二叉树。 2. 应用: 我们用堆排可以实现时间复杂度为 n∗lognn * lognn∗logn 排序。 3. 类型: 大顶堆(堆顶是堆里最大的元素),小顶堆(堆顶是堆里最小的元素)。 下面...

C'est la vie! 1563

堆的相关操作及应用

这里的堆不是操作系统里叫作“堆”的内存段,而是是一种数据结构,本质是完全二叉树。相比于一般的二叉树,堆又有着自己特点,根据这个特点,堆分为大根堆和小根堆。

qq_56475924的博客 1065

C++ STL堆操作

/* STL 最大堆、最小堆的应用 */ #include <iostream> #include <vector> #include <algorithm> // using namespace std; /* STL 堆操作 (1)make_heap()构造堆 void make_heap(first_pointer,end...

weixin_30471065的博客 191

堆操作模板

#include<iostream> #include<string> using namespace std; const int N = 1e5 + 10; int h[N],ph[N],hp[N],n,cnt,m; // cnt表明现在容器中总的元素个数(可以作为容器末尾元素的指针) // m记录当前所使用元素的序号 // p理解为pointer指针 h理解为heap ph是从指针数组指向堆的映射 ph[k] 通俗理解就是第k个插入的元

qq_45651829的博客 147

关于堆的操作

/* 堆操作 来源:Data Structures with C++ Using STL */ #include #include #include #include using namespace std; //调整堆的顺序 template void adjustHeap(vector& v, int first, int last, Compare comp) { int c

孙小小子的博客 451

8.2 建堆操作

在某些情况下,我们希望使用一个列表的所有元素来构建一个堆,这个过程被称为“建堆操作”。

tyb333333的博客 601

操作系统堆/JVM堆/数据结构堆各自的功能

逆水行舟,不进则退!!!

m0_63852716的博客 611

堆-堆的基本概念与操作

堆(heap)又名优先队列(priority queue),是一种特殊的树。 1. 堆的两个性质: ① structure property: 是一个完全二叉树; 因此可用数组表示,BT[n+1]的形式,BT[0]为dummy. ② order property: (min heap为例,大小关系变反之后则为max heap) 表述一:每个子树的根的值都比子树中其他值小; 表述二:每个结点的值都比左右子小; 表述三:从根到任何叶的(唯一)路径上,结点的值递增; 2. 堆的父子结点 3. 堆的基本操作 (

SydneyCarton_的博客 896
上一篇: (一)操作系统基础总结一
下一篇: JIT编译器技术理解
JayInnn
博客等级 码龄9年 4粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值