• <知识整理>树--堆及其应用


    预备知识: 

      完全二叉树的定义:一个深度为k数的二叉树(设根节点的深度为1),若二叉树深度从1到k-1层都是满的,而第k层的节点都集中在左边(即第k层不存在两节点之间有空缺),那么此数就被叫做完全二叉树。

      完全二叉树有几个重要的性质(编号从根节点由1开始广度优先从左到右排):

      编号为i的节点左儿子(如果有的话)的编号为2*i,右儿子(如果有的)的编号为2*i+1,父节点(如果有的话)的编号为i/2。由此还可知道i节点有父亲的充要条件是i/2>=1,有儿子的充要条件是i*2<=size(size为该完全二叉树最大点编号)

    堆的概述:

      堆(heap)用数组存储,可看做一个完全二叉树,数组元素的下标即树节点的编号,故可由上性质知a[i]的父亲(如果有的话)为a[i/2],左儿子和右儿子(如果有的话)分别为a[i*2]和a[i*2+1]。

      大根堆:父亲>=儿子;小根堆:父亲<=儿子。由大小根堆定义知堆顶一定是大根堆里最大、小根堆里最小的元素。

      堆的核心操作为put操作(向堆里添一个元素)和get操作(取出堆顶并删除)。

    以小根堆为例讲解二操作:

      put:1.在堆尾插入一个元素,设其为当前节点;

       2.当前节点与其父亲(如果有的话,否则直接结束)比较;

       3.若比父亲小,与父亲交换值,更新当前节点为父节点,并继续重复第2步:否则结束。

      核心代码:

     1 void put(int x)
     2 {
     3     heap[++heap_size]=x;
     4     int now,next;//当前节点,父亲节点
     5     now=heap_size;
     6     while(now>1)
     7     {
     8                 next=now>>1;
     9         if(heap[now]>=heap[next]) return;
    10         swap(heap[now],heap[next]);
    11         now=next;
    12     }
    13 }            

      get:1.保存堆顶元素,让最后一个元素覆盖堆顶元素,堆的大小减一,设当前节点为根节点;

      2.当前节点与其儿子(如果有的话,否则之间结束、返回保存的堆顶元素)中值最小的比较;

      3.若比儿子大,交换它们的值,更新当前节点为该儿子节点,继续第2步比较;否则结束,并返回保存的堆顶元素。

      核心代码:

    int get()
    {
            int ans=heap[1];
        heap[1]=heap[size--];
        int now=1,next;
        while(now*2<=size)
        {
            next=now*2;
            if(next<size&&heap[next+1]<heap[next]) next++;//找到最小的儿子
            if(heap[now]<=heap[next]) break;
            swap(heap[next],heap[now]);
            now=next;
        }
            return ans;
    }

      如为大根堆,只需比较时让大的“下潜”就行。

      时间复杂度:都是O(log n)

    应用:

      1.堆排序:

        由大小根堆定义知堆顶一定是大根堆里最大、小根堆里最小的元素,便可将待排元素一个个put到一个队里,并一个个get出来,时间复杂度为O(n log n)。

      2.STL优先队列(实质是堆):特点是可以自动排序,详情见大佬博客:

      https://blog.csdn.net/qq_19656301/article/details/82490601

    ~~~

    最后BB:

      可见堆的时间复杂度都是最坏情况的复杂度,个人认为数据极好的话堆排序应该比sort快。。。 不过普通数据用sort准没错。。。

    (日后可能更新)

  • 相关阅读:
    关于抽象类
    封装.继承.多态
    构造方法
    String
    无参方法与有参方法
    类和对象
    使用分层实现业务处理(二)
    使用分层实现业务处理(一)
    序列化Serializable接口
    用JSP从数据库中读取图片并显示在网页上
  • 原文地址:https://www.cnblogs.com/InductiveSorting-QYF/p/10776293.html
Copyright © 2020-2023  润新知