10.2 堆

参考博客: https://blog.csdn.net/weixin_41698717/article/details/107789354

本章问题

1.完全二叉堆的堆序性是什么

堆序性:堆顶之外的每个节点都不大于其父节点。

2.完全二叉堆中的上滤是如何操作的

对第i 个词条进行上滤,
查看该节点的父亲是否小于该节点,
1.如果小于该节点,与父节点交换,然后对父节点位置进行上滤
2.如果大于该节点,结束上滤, 并返回上滤最终抵达的位置

3.完全二叉堆的插入中是如何查找插入位置的

将词条插入末尾位置,然后对该词条进行上滤操作

4.完全二叉堆中的下滤是如何操作的

1.当左孩子节点存在时,若节点大于父亲,将父节点与左节点交换,之后判断右节点
2.当右孩子节点存在时,若节点大于父亲,将父节点与节点交换。
3.获取三者中的大者,若最大者若不为自己,二者换位,并继续考查下降后的 原父节点

5.完全二叉堆中的删除顶节点的是如何操作的

1.摘除堆顶(首词条),代之以末词条
2.对新堆顶实施下滤

6.Floyd是如何建堆的

从末节点依次遍历到头结点,对每个节点的父亲,依次进行下滤

7.PQ_ComplHeap是如何进行构造的

使用拷贝函数依次复制元素到堆中,然后进行Floyd建堆。

8.在PQ_ComplHeap.h文件中生成heapsort失败

将vector中堆排序接口权限改为public后,在测试调用堆排序成功,若是protected会出错

10.2.1 PQ_ComplHeap

//"pq.h"
#pragma once

template <typename T> struct PQ { //优先级队列PQ模板类
   virtual void insert ( T ) = 0; //按照比较器确定的优先级次序插入词条
   virtual T getMax() = 0; //取出优先级最高的词条
   virtual T delMax() = 0; //删除优先级最高的词条
};
//"pq_macro.h"
#pragma once
#define  InHeap(n, i)      ( ( ( -1 ) < ( i ) ) && ( ( i ) < ( n ) ) ) //判断PQ[i]是否合法
#define  Parent(i)         ( ( i - 1 ) >> 1 ) //PQ[i]的父节点(floor((i-1)/2),i无论正负)
#define  LastInternal(n)   Parent( n - 1 ) //最后一个内部节点(即末节点的父亲)
#define  LChild(i)         ( 1 + ( ( i ) << 1 ) ) //PQ[i]的左孩子
#define  RChild(i)         ( ( 1 + ( i ) ) << 1 ) //PQ[i]的右孩子
#define  ParentValid(i)    ( 0 < i ) //判断PQ[i]是否有父亲
#define  LChildValid(n, i) InHeap( n, LChild( i ) ) //判断PQ[i]是否有一个(左)孩子
#define  RChildValid(n, i) InHeap( n, RChild( i ) ) //判断PQ[i]是否有两个孩子
#define  Bigger(PQ, i, j)  (  PQ[i] <=  PQ[j]  ? j : i ) //取大者(等时前者优先)
#define  ProperParent(PQ, n, i) /*父子(至多)三者中的大者*/ \
            ( RChildValid(n, i) ? Bigger( PQ, Bigger( PQ, i, LChild(i) ), RChild(i) ) : \
            ( LChildValid(n, i) ? Bigger( PQ, i, LChild(i) ) : i \
            ) \
            ) //相等时父节点优先,如此可避免不必要的交换
10.2.1.1 PQ_ComplHeap ADT接口
操作接口功能描述
percolateDown(n,i )对向量前n个词条中的第i个实施下滤,i < n
percolateUp(i )对向量中的第i个词条实施上滤操作
heapify(n )Floyd建堆算法
PQ_ComplHeap( )默认构造
PQ_ComplHeap(A,n )批量构造
insert ( T )按照比较器确定的优先级次序,插入词条
getMax( )读取优先级最高的词条
delMax( )删除优先级最高的词条
10.2.1.2 PQ_ComplHeap类模板
#include "vector.h" //借助多重继承机制,基于向量
#include "pq_macro.h"
#include "pq.h" //按照优先级队列ADT实现的
template <typename T> class PQ_ComplHeap : public PQ<T>, public Vector<T> { //完全二叉堆
//    /*DSA*/friend class UniPrint; //演示输出使用,否则不必设置友类
protected:
   Rank percolateDown ( Rank n, Rank i ); //下滤
   Rank percolateUp ( Rank i ); //上滤
   void heapify ( Rank n ); //Floyd建堆算法
public:
   PQ_ComplHeap() { } //默认构造
   PQ_ComplHeap ( T* A, Rank n ) { this->copyFrom ( A, 0, n ); heapify ( n ); } //批量构造
   void insert ( T ); //按照比较器确定的优先级次序,插入词条
   T getMax(); //读取优先级最高的词条
   T delMax(); //删除优先级最高的词条
}; //PQ_ComplHeap
10.2.1.3 getMax
//getMax()
template <typename T> T PQ_ComplHeap<T>::getMax() {  return this->_elem[0];  }
10.2.1.4 insert
//insert
template <typename T> void PQ_ComplHeap<T>::insert ( T e ) { //将词条插入完全二叉堆中
   Vector<T>::insert ( e ); //首先将新词条接至向量末尾
   percolateUp ( this->_size - 1 ); //再对该词条实施上滤调整
}
10.2.1.5 delMax()
//delMax()
template <typename T> T PQ_ComplHeap<T>::delMax() { //删除非空完全二叉堆中优先级最高的词条
   T maxElem = this->_elem[0]; this->_elem[0] = this->_elem[ --this->_size ]; //摘除堆顶(首词条),代之以末词条
   percolateDown ( this->_size, 0 ); //对新堆顶实施下滤
   return maxElem; //返回此前备份的最大词条
}
10.2.1.5 percolateUp()
//对向量中的第i个词条实施上滤操作,i < _size
template <typename T> Rank PQ_ComplHeap<T>::percolateUp ( Rank i ) {
   while ( ParentValid ( i ) ) { //只要i有父亲(尚未抵达堆顶),则
      Rank j = Parent ( i ); //将i之父记作j
      if (  this->_elem[i] <= this->_elem[j]  ) break; //一旦当前父子不再逆序,上滤旋即完成
      swap ( this->_elem[i], this->_elem[j] ); i = j; //否则,父子交换位置,并继续考查上一层
   } //while
   return i; //返回上滤最终抵达的位置
}
10.2.1.6 percolateDown
//对向量前n个词条中的第i个实施下滤,i < n
template <typename T> Rank PQ_ComplHeap<T>::percolateDown ( Rank n, Rank i ) {
   Rank j; //i及其(至多两个)孩子中,堪为父者
   while ( i != ( j = ProperParent ( this->_elem, n, i ) ) ) //只要i非j,则
      { swap ( this->_elem[i], this->_elem[j] ); i = j; } //二者换位,并继续考查下降后的i
   return i; //返回下滤抵达的位置(亦i亦j)
}
10.2.1.6 Floyd建堆
//Floyd建堆
template <typename T> void PQ_ComplHeap<T>::heapify ( Rank n ) { //Floyd建堆算法,O(n)时间
   for ( int i = LastInternal ( n ); InHeap ( n, i ); i-- ) //自底而上,依次
/*DSA*/
      percolateDown ( n, i ); //下滤各内部节点
// /*DSA*/for ( int k = 0; k < n; k++ ) {
// /*DSA*/  int kk = k; while ( i < kk ) kk = (kk - 1) / 2;
// /*DSA*/  i == kk ? print(_elem[k]) : print("    " );
// /*DSA*/}; printf("\n");
// /*DSA*/}
}

10.2.2 PQ_ComplHeap.h

#include "vector.h" //借助多重继承机制,基于向量
#include "pq_macro.h"
#include "pq.h" //按照优先级队列ADT实现的
template <typename T> class PQ_ComplHeap : public PQ<T>, public Vector<T> { //完全二叉堆
//    /*DSA*/friend class UniPrint; //演示输出使用,否则不必设置友类
protected:
   Rank percolateDown ( Rank n, Rank i ); //下滤
   Rank percolateUp ( Rank i ); //上滤
   void heapify ( Rank n ); //Floyd建堆算法
public:
   PQ_ComplHeap() { } //默认构造
   PQ_ComplHeap ( T* A, Rank n ) { this->copyFrom ( A, 0, n ); heapify ( n ); } //批量构造
   void insert ( T ); //按照比较器确定的优先级次序,插入词条
   T getMax(); //读取优先级最高的词条
   T delMax(); //删除优先级最高的词条
}; //PQ_ComplHeap

//getMax()
template <typename T> T PQ_ComplHeap<T>::getMax() {  return this->_elem[0];  }


//insert
template <typename T> void PQ_ComplHeap<T>::insert ( T e ) { //将词条插入完全二叉堆中
   Vector<T>::insert ( e ); //首先将新词条接至向量末尾
   percolateUp ( this->_size - 1 ); //再对该词条实施上滤调整
}


void swap( int &a, int &b){
   int tmp = a;
   a = b;
   b = tmp;
}
//上滤
//对向量中的第i个词条实施上滤操作,i < _size
template <typename T> Rank PQ_ComplHeap<T>::percolateUp ( Rank i ) {
   while ( ParentValid ( i ) ) { //只要i有父亲(尚未抵达堆顶),则
      Rank j = Parent ( i ); //将i之父记作j
      if (  this->_elem[i] <= this->_elem[j]  ) break; //一旦当前父子不再逆序,上滤旋即完成
      swap ( this->_elem[i], this->_elem[j] ); i = j; //否则,父子交换位置,并继续考查上一层
   } //while
   return i; //返回上滤最终抵达的位置
}

//delMax()
template <typename T> T PQ_ComplHeap<T>::delMax() { //删除非空完全二叉堆中优先级最高的词条
   T maxElem = this->_elem[0]; this->_elem[0] = this->_elem[ --this->_size ]; //摘除堆顶(首词条),代之以末词条
   percolateDown ( this->_size, 0 ); //对新堆顶实施下滤
   return maxElem; //返回此前备份的最大词条
}

//对向量前n个词条中的第i个实施下滤,i < n
template <typename T> Rank PQ_ComplHeap<T>::percolateDown ( Rank n, Rank i ) {
   Rank j; //i及其(至多两个)孩子中,堪为父者
   while ( i != ( j = ProperParent ( this->_elem, n, i ) ) ) //只要i非j,则
      { swap ( this->_elem[i], this->_elem[j] ); i = j; } //二者换位,并继续考查下降后的i
   return i; //返回下滤抵达的位置(亦i亦j)
}

//Floyd建堆
template <typename T> void PQ_ComplHeap<T>::heapify ( Rank n ) { //Floyd建堆算法,O(n)时间
   for ( int i = LastInternal ( n ); InHeap ( n, i ); i-- ) //自底而上,依次
/*DSA*/
      percolateDown ( n, i ); //下滤各内部节点
// /*DSA*/for ( int k = 0; k < n; k++ ) {
// /*DSA*/  int kk = k; while ( i < kk ) kk = (kk - 1) / 2;
// /*DSA*/  i == kk ? print(_elem[k]) : print("    " );
// /*DSA*/}; printf("\n");
// /*DSA*/}
}

template <typename T> void Vector<T>::heapSort (  Rank lo, Rank hi ) { //0 <= lo < hi <= size
   PQ_ComplHeap<T> H ( _elem + lo, hi - lo ); //将待排序区间建成一个完全二叉堆,O(n)
   while ( ! H.empty() ) //反复地摘除最大元并归入已排序的后缀,直至堆空
      _elem[--hi] = H.delMax(); //等效于堆顶与末元素对换后下滤
}

10.2.3 PQ_ComplHeap.h测试

#include "pq_complheap.h"
#include <iostream>
using namespace std;
int main(){
    int A[] = { 4, 2, 5, 1, 3};
    //测试建堆函数
    PQ_ComplHeap<int> a (A, 5);
    //测试getMax
    cout << a.getMax() << endl;//5
    //测试insert
    a.insert( 6 );
    //测试delMax
    cout << a.delMax() << endl;//6
    cout << a.getMax() << endl;//5

    //测试堆排序
    Vector<int> vec(A, 5);
    vec.heapSort( 0, 5);
    for( int i= 0; i<5; ++i )
        cout << vec[i] << " ";//1 2 3 4 5 
}
### 回答1: 电解电容是一种常见的电子元器件,用于存储和放电电能。它通常由两个电极和一个电解质组成,电解质可使电容器具有较大的电容量。 10*10.2 3D封装是指将电解电容器的封装形式,封装是将电子元器件封装在特定的外壳内,以保护其内部结构和提供正确的引脚连接。3D封装是指采用三维立体封装结构,比传统的平面封装更小巧且具有更高的集成度。 10*10.2表示电解电容的封装尺寸大小,它的长和宽分别为10mm和10.2mm。这样的尺寸足够小巧,适用于电子产品中的紧凑空间设计。同时,封装形式也便于安装在电路板上,并与其他元器件连接。 利用10*10.2 3D封装的电解电容器,可以在小型电子设备中起到存储和放电电能的作用。其结构紧凑,能够满足现代电子产品对于小型化和高性能的要求。例如,它可以用于智能手机、平板电脑、耳机等消费电子产品中。此外,由于封装的结构更加紧凑,还可以降低元器件占用的空间,提高电路板的集成度。 总之,电解电容10*10.2 3D封装是一种可以在小型电子设备中使用的电解电容器封装形式。它的小尺寸和紧凑的结构使其适用于紧凑空间设计,并且能够满足现代电子产品对高性能和小型化的需求。 ### 回答2: 电解电容是一种常见的电子器件,用于存储电荷和释放电能。10*10.2是电解电容的尺寸参数之一,表示电容的封装尺寸为10mm×10.2mm。 3D封装是一种封装技术,可以将多个封装层垂直叠在一起,从而在有限的空间内实现更高的器件集成度。电解电容10*10.2 3D封装则表示电解电容在其尺寸为10mm×10.2mm的基础上采用了3D封装技术。 通过采用3D封装技术,电解电容可以在相同的尺寸下实现更大的电容容量。此外,3D封装还可以有效缩小电解电容的封装尺寸,提高器件的空间利用率。通过这种封装方式,电解电容在电子设备中的应用更加灵活多样。 电解电容10*10.2 3D封装可以应用于各种电子设备,如智能手机、平板电脑、数码相机等。其小尺寸和高性能使得电子设备可以更加紧凑和高效。同时,3D封装还可以提高电解电容的可靠性和稳定性,延长器件的使用寿命。 综上所述,电解电容10*10.2 3D封装是一种采用3D封装技术的电容器件,通过提高器件的集成度和性能,满足了现代电子设备对小尺寸、高容量和高可靠性的要求。 ### 回答3: 电解电容是一种电子器件,常用于电路中的滤波、耦合、隔离、存储等功能。而10*10.2 3D封装是指这种电解电容的外观尺寸和形状。 10*10.2是指电解电容的长宽尺寸,单位为毫米。这个尺寸可能会因不同厂商或型号而有所差异,但通常是适合一般电路板上的布局,并且易于安装和焊接。 3D封装表示电解电容的外形形状,即具有三个维度的形状特征。具体来说,3D封装可能包括电解电容体的高度、底座形状、引脚位置和排列等。这些封装特征可以使电解电容更容易集成到电路板上,提高空间利用率和散热效果。 根据电解电容的电路要求,10*10.2 3D封装的电解电容通常具有较大的电容量、较高的工作电压和较低的等效串联电阻。这样可以满足电路对储能、抗干扰和快速响应的需求。在选择电解电容时,需要根据具体的电路设计要求来选择合适的电容值和工作电压,并确保封装符合电路板的布局和连接要求。 总之,电解电容的10*10.2 3D封装是一种常见的外观尺寸和形状,用于满足电路的电容需求,并能轻松集成到电路板上。我们在电路设计和选择电解电容时应该考虑到这些因素,以确保电路的正常运行和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值