数据结构-二叉树(5)利用数组实现堆
#define DefaultSize 10; template <class E> //堆中存储的是一个记录的集合,并根据每个记录的关键码以最小堆序排序,在使用堆操作之前需要定义记录的结构类型,用E表示 class MinHeap:public PQueue<E>{ //最小堆类继承了最小优先级队列 public: MinHeap(int sz=DefaultSize); MinHeap(E arr[],int n); ~MinHeap(){delete []heap}; bool Insert(const E& x); bool RemoveMin(E& x); bool IsEmpty()const{return currentSize==0;} bool IsFull()const{return currentSize==maxHeapSize;} void MakeEmpty(){currentSize=0;} private: E *heap; int currentSize; int maxHeapSize; void siftDown(int start,int m); void siftUp(int start); } template <class T> MinHeap<E>::MinHeap(int sz=DefaultSize){ maxHeapSize=(DefaultSize<sz)?sz:DefaultSize; heap=new E[maxHeapSize]; if(heap==NULL){ cerr<<"堆存储分配失败!"<<endl; exit(1); } currentSize=0; } template <class T> MinHeap<E>::MinHeap(E arr[],int n){ //复制构造函数,数组调整成堆 maxHeapSize=(DefaultSize<n)?n:DefaultSize; //取n和DefaultSize中比较大的一个作为最小堆的大小 heap=new E[maxHeapSize]; if(heap==NULL){ cerr<<"堆分配存储失败!"<<endl; exit(1); } for(int i=0;i<n;i++) heap[i]=arr[i]; currentSize=n; int currentPos=(currentSize-2)/2; //找最初调整位置:最后分支结点(最后一个结点的父结点) while(currentPos>=0){ //自底向上逐步扩大成堆 siftDown(currentPos,currentSize-1); //局部自上向下下滑调整 currentPos--; //再向前换一个分支结点 } } template <class T> void MinHeap<E>::siftDown(int start,int m){ //私有函数,从结点start开始到m为止,自上而下比较,如果子女的值小于父结点的值,则关键码小的上浮,继续向下层比较,这样将一个集合局部调整为最小堆 int i=start,j=2*i+1; //j指向i的左子女 E temp=heap[i]; while(j<=m){ if(j<m && heap[j]>heap[j+1]) j++; //让j指向两子女中的小者 if(temp<=heap[j]) break; else{ heap[i]=heap[j]; i=j; j=2*j+1; } } heap[i]=temp; } template <class E> void MinHeap<E>::siftUp(int start){ //私有函数:从结点start开始到结点0为止,自下而上比较,如果子女的值小于父结点的值则相互交换,这样将集合重新调整为最小堆,关键码比较符<=在E的类型中定义 int j=start,i=(j-1)/2; //j指向i的父结点 E temp=heap[j]; while(j>0){ if(heap[i]<=temp)break; else{ heap[j]=heap[i]; j=i; i=(i-1)/2; } } heap[j]=temp; } template <class E> bool MinHeap<E>::Insert(const E& x){ if(currentSize==maxHeapSize){ cerr<<"Heap Full"<<endl; return false; } heap[currentSize]=x; siftUp(currentSize); //向上调整 currentSize++; return true; } template <class E> bool MinHeap<E>::RemoveMin(E &x){ if(!currentSize){ cout<<"Heap empty"<<endl; return false; } x=heap[0]; heap[0]=heap[currentSize-1]; currentSize--; siftDown(0,currentSize-1); return true; }
标签:
二叉树
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥