美文网首页
数据结构[堆]

数据结构[堆]

作者: 85ca4232089b | 来源:发表于2020-05-21 14:16 被阅读0次

堆是具有下⾯面性质的完全⼆二叉树: 每个结点的值都⼤大于或等于其左右孩⼦子结点的值, 称为⼤大顶堆;如图1; 或者每个结点的值都⼩小于等于其左右孩⼦子的结点的值,称为⼩小顶堆, 如图



堆排序(Heap Sort) 原理理探索


堆排序思路路:
将⽆无需序列列构建成⼀一个堆,根据升序降序需求选择⼤大顶堆或⼩小顶堆
将堆顶元素与末尾元素交换,将最⼤大元素”沉"到数组末端;
重新调整结构,使其满⾜足堆定义,然后继续交换堆顶元素与当前末尾元素,反复 执⾏行行调整+交换步骤,直到整个序列列有序;

堆排序(Heap Sort)代码实现:

堆是具有下⾯面性质的完全二叉树: 每个结 点的值都⼤大于或等于其左右孩⼦子结点的值,称 为大顶堆;

⼆二叉树性质5: 如果对⼀一颗有n个结点的完全⼆二叉树的结点按层序编号,对任⼀一结点i (1 ≤ i ≤ n) 有:
如果 i = 1 ,则结点 i 是⼆二叉树的根. ⽆无双亲. 如果 i > 1,则其双亲是结点 [ i / 2 ];
如果 2i > n ,则结点 i ⽆无左孩⼦子 (结点i 为叶⼦子结点); 否则左孩⼦子是结点 2i;
如果 2i + 1 > n ,则结点 i ⽆无右孩⼦子; 否则其右孩⼦子是结点 2i+1;

堆排序(Heap Sort) — 复杂度分析

//大顶堆调整函数;
/*
 条件: 在L.r[s...m] 记录中除了下标s对应的关键字L.r[s]不符合大顶堆定义,其他均满足;
 结果: 调整L.r[s]的关键字,使得L->r[s...m]这个范围内符合大顶堆定义.
 */
void HeapAjust(SqList *L,int s,int m){
    
    int temp,j;
    //① 将L->r[s] 存储到temp ,方便后面的交换过程;
    temp = L->r[s];
    
    //② j 为什么从2*s 开始进行循环,以及它的递增条件为什么是j*2
    //因为这是颗完全二叉树,而s也是非叶子根结点. 所以它的左孩子一定是2*s,而右孩子则是2s+1;(二叉树性质5)
    for (j = 2 * s; j <=m; j*=2) {
        
        //③ 判断j是否是最后一个结点, 并且找到左右孩子中最大的结点;
        //如果左孩子小于右孩子,那么j++; 否则不自增1. 因为它本身就比右孩子大;
        if(j < m && L->r[j] < L->r[j+1])
            ++j;
        
        //④ 比较当前的temp 是不是比较左右孩子大; 如果大则表示我们已经构建成大顶堆了;
        if(temp >= L->r[j])
            break;
        
        //⑤ 将L->[j] 的值赋值给非叶子根结点
        L->r[s] = L->r[j];
        //⑥ 将s指向j; 因为此时L.r[4] = 60, L.r[8]=60. 那我们需要记录这8的索引信息.等退出循环时,能够把temp值30 覆盖到L.r[8] = 30. 这样才实现了30与60的交换;
        s = j;
    }
    
    //⑦ 将L->r[s] = temp. 其实就是把L.r[8] = L.r[4] 进行交换;
    L->r[s] = temp;
}


//10.堆排序--对顺序表进行堆排序
void HeapSort(SqList *L){
    int i;
   
    //1.将现在待排序的序列构建成一个大顶堆;
    //将L构建成一个大顶堆;
    //i为什么是从length/2.因为在对大顶堆的调整其实是对非叶子的根结点调整.
    for(i=L->length/2; i>0;i--){
        HeapAjust(L, i, L->length);
    }
    
    
    //2.逐步将每个最大的值根结点与末尾元素进行交换,并且再调整成大顶堆
    for(i = L->length; i > 1; i--){
        
        //① 将堆顶记录与当前未经排序子序列的最后一个记录进行交换;
        swap(L, 1, i);
        //② 将L->r[1...i-1]重新调整成大顶堆;
        HeapAjust(L, 1, i-1);
    }
}

相关文章

  • 堆结构的实现

    堆的定义: 这里的堆是指一种数据结构(或数据结构属性),非指堆内存。堆属性用二叉树来体现,具有堆属性的数据结构才可...

  • 看图说话数据结构之二项队列(优先队列)——原理解析

    数据结构之二叉堆(优先队列)——原理解析,数据结构之二叉堆(优先队列)——java实现,数据结构之左式堆(优先队列...

  • 栈和堆以及栈区和堆区的区别

    栈和堆以及栈区和堆区的区别 数据结构中的栈和堆 栈:具有先进后出性质的数据结构 堆:一种经过排序的树形数据结构,节...

  • 数据结构中堆、栈和队列的理解

    一、堆 堆是一种经过排序的树形数据结构,每个节点都有一个值,通常我们所说的堆的数据结构是指二叉树。所以堆在数据结构...

  • iOS堆、栈和队列

    堆 堆是一种经过排序的树形数据结构,每个节点都有一个值,通常我们所说的堆的数据结构是指二叉树。所以堆在数据结构中通...

  • 通俗易懂:C语言中内存堆和栈的区别

    数据结构的栈和堆 首先在数据结构上要知道堆栈,尽管我们这么称呼它,但实际上堆栈是两种数据结构:堆和栈。 堆和栈都是...

  • 数据结构--堆

    堆有两个特性: 堆是一个完全二叉树 堆中所有父节点都大于(最大堆)或者小于(最小堆)子结点。在一般的实现中,我们可...

  • 数据结构-堆

    堆(最小堆) I 堆化操作 遍历根节点,并且每个根节点都做到下沉。 II 出堆 放出堆顶的元素, 把最后一个元素放...

  • 数据结构-堆

    定义 优先队列:一种特殊的队列,队列中元素出栈的顺序是按照元素的优先权大小,而不是元素入队的先后顺序。 堆的特性:...

  • 数据结构-堆

    堆(heap)又被为优先队列(priority queue)。尽管名为优先队列,但堆并不是队列。回忆一下,在队列中...

网友评论

      本文标题:数据结构[堆]

      本文链接:https://www.haomeiwen.com/subject/nyvzohtx.html