美文网首页
堆的相关操作与堆排序

堆的相关操作与堆排序

作者: ___Qian___ | 来源:发表于2019-03-08 10:42 被阅读0次

堆中插入、删除元素

先看图解:


堆的插入与删除图解

堆中插入元素

插入元素总是插入在数组中的最后一个位置,然后从其父节点依次向上调整堆,执行元素“上浮”操作。

//在最小堆中加入新的数据nNum
void addNumber(int[] a, int n, int nNum)
{
    a[n] = nNum;
    fixup(a, n);
}

//  新加入i结点  其父结点为(i - 1) / 2
void fixup(int[] a, int i)
{
    int j, temp;
    
    
    j = (i - 1) / 2;      //父结点
    while (j >= 0 && i != 0)     
    {
        if (a[j] <= a[i])       
            break;
        //父节点比当前节点大
        swap(a,i,j);    //当前节点与它的父节点交换,上浮

        i = j;      //继续向上调整堆
        j = (i - 1) / 2;
    }
    
}
//更简洁的写法:
void fixup2(int[] a, int i)
{
    for (int j = (i - 1) / 2; 
           (j >= 0 && i != 0)&& a[i] > a[j];
            i = j, j = (i - 1) / 2)

        swap(a, i, j);
}

堆中删除元素

删除元素时,总是删除堆顶元素,后将堆中最后一个元素放置对顶,从堆顶到叶子节点依次向下调整堆,执行元素“下沉操作”。

//在最小堆中删除数
void deleteNumber(int[] a, int n)
{
    swap(a[0], a[n - 1]);
    fixdown(a, 0, n - 1);
}
//  从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2
void fixdown(int[] a, int i, int n)
{
    int j, temp;
 
    temp = a[i];
    j = 2 * i + 1;
    while (j < n)
    {
        if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的
            j++;
 
        if (a[j] >= temp)
            break;
 
        swap(a,i,j);   //与左右孩子中最小的交换,下沉

        i = j;            //继续向下调整堆
        j = 2 * i + 1;
    }

}

堆的初始化

有了堆的插入和删除后,再考虑下如何对一个数据进行堆化操作。
从最后一个非叶子结点,直至根节点,自底向上,对以这些节点为根节点的子树逐渐执行元素下沉操作。

//建立最小堆
void MakeMinHeap(int[] a, int n)
{
    for (int i = n / 2 - 1; i >= 0; i--)
        fixdown(a, i, n);
}

堆排序的完整代码

void minHeapSort(int[] a, int n)
{
    makeMinHeap(a,n);
    for (int i = n - 1; i >= 1; i--)
    {
        swap(a[i], a[0]);
        fixdown(a, 0, i);
    }
}

void makeMinHeap(int[] a, int n)
{
    for (int i = n / 2 - 1; i >= 0; i--)
        fixdown(a, i, n);
}

void fixdown(int[] a, int i, int n)
{
    int j, temp;
 
    temp = a[i];
    j = 2 * i + 1;
    while (j < n)
    {
        if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的
            j++;
 
        if (a[j] >= temp)
            break;
 
        swap(a,i,j);   //与左右孩子中最小的交换,下沉

        i = j;            //继续向下调整堆
        j = 2 * i + 1;
    }

}

相关文章

  • 堆的相关操作与堆排序

    堆中插入、删除元素 先看图解: 堆中插入元素 插入元素总是插入在数组中的最后一个位置,然后从其父节点依次向上调整堆...

  • 每日python——python中的堆排序模块heapq

    python中的heapq模块提供了与堆排序有关的操作,关于堆的理解可以自行网上搜索相关知识,需要清楚的是,pyt...

  • HeapSort堆排序详解

    本文我们来学习下堆排序的实现原理,堆排序顾名思义就是利用了堆的特点来实现排序,首先了解堆是什么? 堆相关的一些概念...

  • 堆 | 定义、操作、堆排序

    参考:胡凡,曾磊《算法笔记》 定义 堆是一棵完全二叉树。 完全二叉树:结点数量n,叶子结点数ceiling(n/2...

  • 堆排序

    前言 本文主要介绍堆的构造, 元素在堆中的上浮操作以及下沉操作,最后讲述基于这些操作的堆排序, 不对优先队列作介绍...

  • 堆与堆排序

    鸣谢:https://www.cnblogs.com/chengxiao/p/6129630.htmlhttps:...

  • 堆与堆排序

    因为堆(二叉堆)是一个完全二叉树,所以一般使用数组来存放 堆的性质 一句话来说就是父节点比子节点的数据要小(小顶堆...

  • 堆与堆排序

    堆 堆是具有下列性质的完全二叉树:每个节点的值都大于或等于左右孩子节点的值,称为大顶堆;每个节点的值都小于或等于左...

  • 堆与堆排序

    姓名:毛浩 学号:17029250003 【嵌牛导读】一道力扣题。 【嵌牛鼻子】力扣 【嵌牛提问】如何解决同位...

  • 堆与堆排序

    堆(大顶堆)的概念 堆是一种特殊的二叉树,大顶堆就是根节点为最大值的堆,它具有如下的特点: 堆是完全二叉树 堆常用...

网友评论

      本文标题:堆的相关操作与堆排序

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