美文网首页
数据结构-堆、shiftUP、shiftDown、heapify

数据结构-堆、shiftUP、shiftDown、heapify

作者: 羽裳有涯 | 来源:发表于2020-03-31 15:47 被阅读0次

堆排序

堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

shiftUP

用于创建堆,不知道有多少数据;
以父子数大小来排序;
第一个为数组1 这样父子树的下标为k/2;

//堆第一个为数组1  这样父子树的下标为k/2;
void MaxHeap::shiftUp(int k) {
//    while (k > 1) {
//        int parent = (k)/2;
//        if (data[k] > data[parent]) {
//            std::swap(data[k], data[parent]);
//            k = parent;
//        }else {
//            break;
//        }
//    }
    
//优化写法
    while (k > 1 && data[k] > data[k/2]) {
        std::swap(data[k], data[k/2]);
        k = k/2;
    }
}

shiftDown

  • 用于移除最大值后,仍然是个堆
  • 用于已知数据,排成一个堆
    以左右子数与父子数比较来排序

1、 递归写法

//当shifup 把最大值和最后一个交换时,然后移除最大值,然后shifdown 重新排序
void MaxHeap::shiftDown(int k) {
    //递归
    int l = 2 * k;
    int r = 2 * k + 1;
    int max = k;
    if (l <= count && data[max] < data[l]) {
        max = l;
    }
    if (r <= count && data[max] < data[r]) {
        max = r;
    }
    if (max != k) {
        std::swap(data[max], data[k]);
        shiftDown(max);
    }
}

2、非递归

void MaxHeap::shiftDown(int k) {
    //非递归
    while (2 * k + 1 <= count) {
        int l = k * 2;
        if (l + 1 <= count && data[l] < data[l + 1]) {
            l++;
        }
        if(data[k] > data[l]){
            return;
        }else {
            std::swap(data[k], data[l]);
            k = l;
        }
    }
}

Heapify

对于一组已知数据,只要对

下面是i为0时的例子
Heapify :将堆的末端子节点作调整,使得子节点永远小于父节点。

I 为目标借点下标
parent :为I节点父节点
c1为左子节点
c2为右子节点

parent = (I - 1)/2;

c1 = 2* I + 1;
c2 = 2*I + 2;
image.png

C 实现代码

void heapify(int *arr, int n, int i) {
    if (i >= n) {
        return;
    }
    int c1 = 2 * i + 1;
    int c2 = 2 * i + 2;
    int maxPartent = i;
    if (c1 < n && arr[c1] > arr[maxPartent]) {
        maxPartent = c1;
    }
    if (c2 < n && arr[c2] > arr[maxPartent]) {
        maxPartent = c2;
    }
    
    if (maxPartent != i) {
        int temp = arr[i];
        arr[i] = arr[maxPartent];
        arr[maxPartent] = temp;
        
        heapify(arr, n, maxPartent);
    }

}

void heapify_sort_build(int *arr, int num) {
    int last = num - 1;
    int parent = (last - 1)/2;
    for (int i = parent; i >= 0; i--) {
        heapify(arr, num, i);
    }
}

void heapify_sort_paixu (int *arr, int num) {
    heapify_sort_build(arr, num);
    for (int i = num - 1; i>= 0; i--) {
        int temp = arr[i];
        arr[i] = arr[0];
        arr[0] = temp;
        heapify_sort_build(arr, i);
        
    }
}

void heapify_sort_start(int *arr, int length) {
//    heapify_sort_build(arr, length);
    heapify_sort_paixu(arr, length);
}

相关文章

  • 数据结构-堆、shiftUP、shiftDown、heapify

    堆排序 堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 ...

  • 写了一个堆排序

    堆堆是一颗完全二叉树堆中节点不大于或者不小于其父节点 入堆:直接放入堆内部数据结构的最后,通过shiftUp操作,...

  • 堆排序(大顶堆)

    主要是围绕heapify操作 建堆,从下往上对每一个父节点heapify。第一个父节点的下标是 ((n -1)-1...

  • 堆1 最小的k个数 / 数据流第k大元素

    首先认识堆: 1、认识python3中关于堆的函数 1)heapq.heapify可以原地把一个list调整成堆[...

  • MaxHeap / MinHeap / PriorityQueu

    复盘: 优化了shiftDown的判断减少了重复代码 , 在遍历中做部分边界条件终止 shiftDown 边界定义...

  • 算法-堆排序

    堆排序分两步:建堆:把数组中元素按照堆的结构排成一定的顺序排序:把有序的堆结构的数组元素排成升序heapify本质...

  • Heapify

    Heapify这个函数要会手写。今天不会写,丢人了 :(heapify要从用percolateDown的方法来写。...

  • 堆相关算法

    转发 C 堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Heapify实现的。...

  • 为什么堆化 heapify() 只用 O(n) 就做到了?

    heapify() 前面两篇文章介绍了什么是堆以及堆的两个基本操作,但其实呢,堆还有一个大名鼎鼎的非常重要的操作,...

  • 一步一步学习数据结构和算法 (四) 索引堆

    索引堆 之前建立堆的过程中所存在的问题 将一个数组进行 heapify 之后, 数组元素的位置发生了变化, 有两个...

网友评论

      本文标题:数据结构-堆、shiftUP、shiftDown、heapify

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