首页 > 编程语言 > 详细

小根堆的建立及siftDown与siftUp算法

时间:2020-07-28 21:43:13      阅读:107      评论:0      收藏:0      [点我收藏+]
//最大堆的构建、结点的插入和删除与此完全类似
#include<iostream>
using namespace std;

class MinHeap
{
public:
    int* heap;//存放最小堆中元素的数组
    int maxHeapSize;//最小堆最多允许元素个数
    int currentSize;//最小堆中当前元素个数
public:
    MinHeap(int sz){
        maxHeapSize=sz;
        heap=new int[maxHeapSize];
        currentSize=0;
    }
    MinHeap(int arr[],int n,int sz){  //数组传参后,传的是指针,sizeof(arr)不能计算出该数组有多少个字节,而是该指针变量所占字节,
        maxHeapSize=sz;               //在这里sizeof(arr)=4
        heap=new int[maxHeapSize];
        for(int i=0;i<n;i++){
            heap[i]=arr[i];
        }
        currentSize=n;
        int currentPos=(currentSize-1-1)/2;//堆(完全二叉树)的最后一个节点的父节点
        while(currentPos>=0){
            siftDown(currentPos,currentSize-1);
            currentPos--;
        }
    }
    void siftDown(int start,int m)  //m接收的实参是堆(完全二叉树)的最后一个节点
    {
        int i=start,j=2*i+1;   //i指父结点,j指左孩子结点
        int temp=heap[i];
        while(j<=m)
        {
            if(j<m&&heap[j]>heap[j+1])
            {
                j++;
            }
            if(temp<=heap[j])
            {
                break;
            }
            else
            {
                heap[i]=heap[j];
                i=j;
                j=2*j+1;
            }
        }
        heap[i]=temp;
    }
    void siftUp(int start)
    {
        int j=start,i=(j-1)/2;  //j可为左孩子也可右孩子,i指父结点
        int 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;
    }
    bool Insert(int x)
    {
        if(currentSize==maxHeapSize)
        {
            return false;
        }
        heap[currentSize]=x;
        siftUp(currentSize);
        currentSize++;
        return true;
    }
    int RemoveMin()
    {
        if(!currentSize)
        {
            return false;
        }
        int x=heap[0];
        heap[0]=heap[currentSize-1];
        currentSize--;
        siftDown(0,currentSize-1);
        return x;
    }
    void show(){
        for(int i=0;i<currentSize;i++){
            cout<<heap[i]<<" ";
        }
    }
};

int main()
{
    int arr[]={53,17,78,9,45,65,87,23};
    int n=sizeof(arr)/sizeof(int);
    MinHeap minHeap(arr,n,50);
    minHeap.show();
    cout<<endl;
    minHeap.Insert(1);//插入1
    minHeap.show();
    cout<<endl;
    cout<<"删除的堆顶元素:"<<minHeap.RemoveMin()<<endl;//删除堆顶元素,并返回原堆顶元素
    minHeap.show();
    cout<<endl;
    return 0;
}
//9 17 65 23 45 78 87 53
//1 9 65 17 45 78 87 53 23
//删除的堆顶元素:1
//9 17 65 23 45 78 87 53

 

小根堆的建立及siftDown与siftUp算法

原文:https://www.cnblogs.com/zzyf/p/13392675.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!