堆(二叉堆)

作者: 修夏之夏i | 来源:发表于2018-08-29 16:40 被阅读13次
堆:关键码的集合。

小堆(大堆):任一结点的关键码均小于等于(大于等于)它的的左右孩子的关键码,位于堆顶结点的关键码最小(最大),从根结点到每个节点的路径上数组元素组成的序列都是递增(递减)的。


最小堆 & 最大堆.png

堆存储在下标为0的数组中。
已知 child :::::: 得parent=(child-1)/2
已知 parent :::::: 得 left=2parent+1
:::::: ::::: ::::::: :::::::::right=2
parent+2

向下调整的应用
  • 堆的创建
  • 堆的删除(只能删除堆顶元素,最后一个元素替代堆顶元素,向下调整以满足堆的性质)
向上调整的应用
  • 堆的插入 (只能在堆最后插入,插入之后,当堆中的元素不再满足堆的性质时,就需要对堆进行向上调整)

Heap.h

#define _CRT_SECURE_N0_WARNINGS 1

#include <stdio.h>
#include <assert.h>

typedef struct Heap{
    int array[100];
    int size;
}Heap;

static void Swap(int *a, int *b)
{
    int t = *a;
    *a = *b;
    *b = t;
}

//初始化
void HeapInit(Heap *pH, int source[], int size)
{
    for (int i = 0; i < size; i++)
    {
        pH->array[i] = source[i];
    }
    //更改堆的实际大小
    pH->size = size;
}

//向下调整 大堆
//root 指的是下标
void HeapAdjustDown(Heap* pH, int root)
{
    int parent = root;
    
    while (1)
    {
        // 先判断有没有孩子(叶子结点)
        // 数组角度去想   -> 孩子的下标是否越界
        // 只要判断左孩子的下标(因为是完全二叉树)
        int left = parent * 2 + 1;
        int right = parent * 2 + 2;

        if (pH->size < left) //越界 左孩子不存在
            return;

        int MaxChild = left;
        if ((pH->size >= right) && (pH->array[right]>pH->array[MaxChild]))
            MaxChild = right;

        if (pH->array[MaxChild] < pH->array[parent])
            return;

        //交换 
        int temp = pH->array[MaxChild];
        pH->array[MaxChild] = pH->array[parent];
        pH->array[parent] = temp;

        parent = MaxChild;
    }
}

//向上调整 大堆

void HeapAdjustUp(Heap* pH, int child)
{
    int parent;
    while (child > 0)
    {
        parent = (child - 1) / 2;
        if (pH->array[parent] >= pH->array[child])
            return;

        Swap(pH->array + parent, pH->array + child);

        child = parent;
    }
}

void HeapMakeHeap(Heap* pH)
{
    //最后一个非叶子结点 last=size-1;
    //parent=(last-1)/2 = size/2-1;
    //所有非叶子结点的下标为[0 ,size/2-1]
    //从物理结构上来看 从后往前建堆 [最后一个非叶子结点size/2-1,0]
    for (int i = (pH->size - 2) / 2; i >= 0; i--) {
        HeapAdjustDown(pH, i);
    }
}

void HeapPop(Heap* pH)
{
    pH->array[0] = pH->array[pH->size - 1];
    pH->size = pH->size - 1;

    HeapAdjustDown(pH, 0);
}

int HeapTop(Heap* pH)
{
    return pH->array[0];
}

void HeapPush(Heap* pH,int data)
{
    assert(pH->size < 100);
    pH->array[pH->size++] = data;

    HeapAdjustUp(pH, pH->size-1);
}



void Test()
{
    int array[] = { 53, 17, 78, 9, 45, 65, 87, 23, 31 };
    int size = sizeof(array) / sizeof(int);

    Heap    heap;
    HeapInit(&heap, array, size);
    HeapMakeHeap(&heap);

    HeapPop(&heap);

    HeapPush(&heap, 100);
    printf("%d\n", HeapTop(&heap));

    printf("建堆完成\n");
}

Main.c

#define _CRT_SECURE_N0_WARNINGS 1

#include "Heap.h"

int main()
{
    //Test(); 
    return 0;
}

相关文章

  • 用go实现二叉堆插入删除构建

    二叉堆的插入: 二叉堆的删除: 二叉堆的构建:

  • 堆(二叉堆)

    堆:关键码的集合。 小堆(大堆):任一结点的关键码均小于等于(大于等于)它的的左右孩子的关键码,位于堆顶结点的关键...

  • 堆排序(下):最大堆

    二叉堆,简称堆 Heap 尖的完全二叉树。也有三叉堆以及普通堆,但大部分时候堆就是指二叉堆 二叉堆的定义 一棵完全...

  • 二叉堆(Binary Heap)

    二叉堆这个数据结构有点意思,自己做了个总结,内容结构如下: 二叉堆性质 二叉堆操作 应用 二叉堆性质: 堆(Hea...

  • [数据结构与算法-iOS 实现]二叉堆原理实现及top k 问题

    二叉堆 demo 二叉堆其实就是一颗完全二叉树,所以又可以叫做完全二叉堆 二叉堆的底层可以用数组来实现 对于二叉堆...

  • 二叉堆

    二叉堆定义 二叉堆是一种特殊的堆, 二叉堆是完全二叉树或者近似完全二叉树. 二叉堆满足堆特性: 父节点的键值总是保...

  • Sort.堆排序(heapsort) & 优先队列

    二叉堆 这个二叉堆和先进后出的那个堆不是一个。而且这个二叉堆从下标1开始存储元素。 这里的二叉堆是个数组,也可以看...

  • PriorityQueue源码解析

    PriorityQueue 一个基于优先级堆的无界优先级队列。 二叉堆 可视化操作:二叉堆 二叉堆(The bin...

  • 堆(Heap)

    堆 堆也是一种树状的数据结构,常见的堆实现有: 二叉堆(Binary Heap, 完全二叉堆) 多叉堆(D-hea...

  • 二叉堆的Python实现

    二叉堆(binary heap)是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树。二叉堆满足堆特性:父节点的...

网友评论

    本文标题:堆(二叉堆)

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