• 最小堆


    在一些应用中,通常需要先收集一部分数据,从中挑选出具有最小或最大关键码的记录开始处理,接着,可能会收集更多的数据,并处理当前数据集中具有最大或最小关键码的问题。

    这样的数据结构叫做堆,这里给出最小堆的实现。

    堆是这样一种数据结构,其根结点都小于左右子女的完全二叉树。
    1、插入算法:插入到最后一个结点,然后从下往上调整成最小堆。
    2、删除算法:删除根结点,从上往下调整成最小堆。
    3、从下往上调整算法。
    4、从上往下调整算法。

    两类错误:

    1、while(parent>0) //while出错:因为while陷入死循环
    SiftDown(parent); //递归到0

    递归程序中还写了循环,一般会陷入死循环

    2、-842150451 数组打印该值,数组越界

    最下堆的抽象数据类型:

    //最小堆抽象数据类型
    class MinHeap
    {
    public:
    	//构造函数和析构函数
    	MinHeap(int n);
    	~MinHeap();
    
    	//调整算法、插入和删除算法
    	void SiftDown(int start);	//自下而上调整算法,用于插入
    	void SiftUp(int start);		//自上而下调整算法,用于删除
    	bool InsertHeap(int x);	//插入算法
    	int DeleteHeap();		//删除算法
    	void Output();
    
    private:
    	int *heap;			//最小堆根指针
    	int count;			//数组下标
    };
    

    /*
    自下而上调整算法:
    1、定义兄弟结点和父结点。
    2、递归到一棵子树的根结点为止,因为最小堆性质,只要一直递归到根子树,
    就可以保证最小堆的性质。
    */

    void MinHeap::SiftDown(int start)
    {
    	
    	int parent=0;
    	int temp=0;
    	
    	parent=(start-1)/2;	//父结点,2i+1 2i+2 可以用这句话统一表达
    	if(heap[parent]>heap[start])
    	{
    		//最小堆性质不满足,交换
    		temp=heap[parent];
    		heap[parent]=heap[start];
    		heap[start]=temp;
    
    			
    	}
    	if(parent>0)	//while出错:因为while陷入死循环
    	SiftDown(parent);	//递归到0
    	
    }
    

    /*
    自上而下调整算法:最小堆,小的元素有聚类的效果,经验
    1、
    */

    void MinHeap::SiftUp(int start)
    {
    	//从0开始到count-1结束
    	int st=start;
    	int temp=0;
    	int child=2*st+1;
    	//从元素较小的子树开始递归
    	if(heap[2*st+1]<heap[2*st+2])
    		;
    	else
    		child=2*st+2;
    	
    	if(heap[st]>heap[child])
    	{
    		temp=heap[st];
    		heap[st]=heap[child];
    		heap[child]=temp;
    	}
    	
    	if(2*child+1<=count-1)	//递归
    		SiftUp(child);
    
    }
    

    /*
    插入算法:
    1、将当前指针数组的值赋值为x。
    2、如果是堆的根指针,则不做任何操作。
    */

    bool MinHeap::InsertHeap(int x)
    {
    	heap[count]=x;		//赋值
    	if(count==0)
    	{
    		//根结点
    		count++;		//自加1
    		return true;
    	}
    	else 
    	{
    		//如果不是根结点
    		SiftDown(count);	//从该结点开始调整为最小堆
    		count++;			//自加1
    		return true;
    	}
    
    }
    

    /*
    删除算法:
    1、用最后一个结点代表根结点。
    2、然后自上而下调整成最小堆。
    */

    int  MinHeap::DeleteHeap()
    {
    	int x;
    	x=heap[0];	//因为插入元素的时候位置指向下一个
    	heap[0]=heap[count-1];	//用最后一个元素代替
    	count--;	//个数减1
    	SiftUp(0);	//自上而下调整成最小堆
    
    	return x;
    }
    

    测试结果:

    -------------最小堆-----------
    ---------输出------
    9 17 65 23 45 78 87 53
    删除的结点:9
    ---------输出------
    17 23 65 53 45 78 87
    删除的结点:17
    ---------输出------
    23 45 65 53 87 78
    请按任意键继续. . .

    最小堆的应用:

    堆排序

    最小生成树

    海量数据处理Topn算法

  • 相关阅读:
    leveldb的搜索
    分布式存储bfs
    golang channel的行为
    支持rotate和大小限制的golang log库
    后台架构 一些需要注意的地方
    不要滥用面向对象,写出难以阅读和修改的代码
    goloader
    逻辑引擎、工作流、CMDB小感
    HTML5学习笔记4
    HTML5学习笔记3
  • 原文地址:https://www.cnblogs.com/fistao/p/3062499.html
Copyright © 2020-2023  润新知