• 算法导论第六章 堆排序


    主要内容:

    堆、最大堆、最小堆的基本概念

    堆的操作:调整、创建、排序

    采用堆实现优先级队列

    基本概念

    heap)亦被称为:优先队列priority queue

    逻辑定义:

    n个元素序列{k1,k2...ki...kn},当且仅当满足下列关系时称之为堆:

    (ki <= k2i,ki <= k2i+1)或者(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4...n/2)

    堆的实现通过构造二叉堆(binary heap),实为二叉树的一种。

    性质

    1、任意节点小于或大于它的所有后裔,最小元或最大元在堆的根上(堆序性)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。

    2、堆总是一棵完全树。堆只需要满足父节点大于两个子节点,而子节点之间没有要求。作为一颗完全树,一层中的节点是从左到右填满的。如果一个节点没有左儿子,那么它一定没有右儿子。并且在第h层中如果存在节点,那么第h-1层必须是填满的。

    堆的操作

    调整堆

    void adjust_max_heap_recursive(int *datas, int length, int i)//递归调用,最大堆调整

    {

        int left,right,largest;

        int temp;

        left = LEFT(i);//left child

        right = RIGHT(i);//right child

        //find the largest value among left and right and i

        if(left<=length && datas[left]>datas[i]) largest = left;

        else largest = i;

        if(right <= length && datas[right] >datas[largest]) largest = right;

        //exchange i and largest

        if(largest != i)

        {

            temp = datas[i];

            datas[i] = datas[largest];

            datas[largest] = temp;

            //recursive call the function, adjust from largest

            adjust_max_heap(datas, length, largest);

        }

    }

    void adjust_max_heap(int *datas,int length,int i)//非递归调用,最大堆调整
    {
        int left,right,largest;
        int temp;
        while(1)
        {
            left = LEFT(i);   //left child
            right = RIGHT(i); //right child
            //find the largest value among left and rihgt and i.
            if(left <= length && datas[left] > datas[i])
                largest = left;
            else
                largest = i;
            if(right <= length && datas[right] > datas[largest])
                largest = right;
            //exchange i and largest
            if(largest != i)
            {
                temp = datas[i];
                datas[i] = datas[largest];
                datas[largest] = temp;
                i = largest;
                continue;
            }
            else
                break;
        }
    }

    创建堆

    思路:逐个加入元素,调整为最大堆或最小堆,直到将所有的元素全部处理完。

    void build_max_heap(int *datas,int length)//创建最大堆
    {
        int i;
        //build max heap from the last parent node
        for(i=length/2;i>0;i—)//从最后一个非叶子节点(n/2)开始到第一个非叶子(1)结束
            adjust_max_heap(datas,length,i);
    }

    堆排序

    思路:创建堆,然后从后往前调整堆。

    void heap_sort(int *datas,int length)
    {
        int i,temp;
        //bulid max heap
        build_max_heap(datas,length);//创建最大堆
        i=length;
        //exchange the first value to the last unitl i=1
        while(i>1)
        {
            temp = datas[i];
            datas[i] = datas[1];
            datas[1] =temp;
            i--;
            //adjust max heap,make sure the fisrt value is the largest
            adjust_max_heap(datas,i,1);
        }
    }

    堆排序算法时间复杂度:调整堆过程满足递归式T(n)<=T(2n/3)+θ(1),有master定义可以知道T(n) = O(lgn),堆排序过程中执行一个循环,调用最大堆调整函数,总的时间复杂度为O(nlgn)。

    优先级队列

    优先级队列有两种:最大优先级队列和最小优先级队列,这两种类别分别可以用最大堆和最小堆实现。

    优先级队列操作(最大优先级队列--最大堆)

    插入:返回最大(优先级)元素:返回最大堆的第一个元素

    最大(优先级)元素出队:删除最大堆的第一个元素,然后把最后一个移动到第一个位置,从第一个位置开始调整堆。

    提高优先级:增加优先级,然后从该节点父节点开始向上调整堆。

    入队:插入堆尾部,然后从该节点父节点开始向上调整堆。

    优先级队列应用

    实现FIFO队列:优先级递增

    实现FILO:优先级递减

  • 相关阅读:
    ci上传图片
    Mac下使用svn命令
    linux 下svn忽略文件
    thinkphp5 隐藏入口和支持pathinfo
    ci tp重定向
    php命名空间
    thinkphp5学习记录一
    Mac下安装homebrew
    使用iTerm2快捷连接SSH
    摄影基础
  • 原文地址:https://www.cnblogs.com/lucas-hsueh/p/3732155.html
Copyright © 2020-2023  润新知