2019-05-12  本文已影响0人  TomyZhang

一、概念

堆是一种基于完全二叉树的数据结构,当一棵完全二叉树满足下列条件时即称为堆:
每个父结点都大于等于(或者小于等于)它的两个子结点。
大于等于的情况称为大根堆,小于等于的情况称为小根堆。

完全二叉树:

小根堆

堆的应用:

堆的存储:
堆的存储通过数组来实现,由于其满足完全二叉树的性质,则对于第i个结点(i从0开始算):
父结点:(i-1)/2 // 为负数时则说明父结点不存在
左右子结点:(i * 2 + 1) 和 (i * 2 + 2)

堆的存储

二、相关操作

堆相关操作

三、实现

#include<stdio.h> 
#define MAX 100

int data[MAX];
int dataIndex = 0;

void swap(int parent, int pos) {
    int temp;
    temp = data[parent];
    data[parent] = data[pos];
    data[pos] = temp;
}

void fix_up() {
    int pos = dataIndex - 1;
    int value = data[pos];
    int parent = (pos - 1) / 2;

    while (parent >= 0 && value < data[parent]) {  //当前结点有父母且值小于父母
        swap(parent, pos);
        pos = parent;
        parent = (pos - 1) / 2;
        value = data[pos];
    }
}

void heap_insert(int val)
{
    data[dataIndex++] = val; //1.放到尾部
    fix_up(); //2.小根堆,向上调整
}

void fix_down(){
    if (dataIndex <= 0) {
        return;
    }
    
    int pos = 0;
    int value = data[pos];
    int left = pos * 2 + 1;
    int right = left + 1;

    while (left < dataIndex) { //左边的结点无越界 
        int refValue;
        int refPos;
        if (right < dataIndex) { //右边的结点无越界 
            refValue = data[left] < data[right] ? data[left] : data[right]; //获取子结点中较小的值 
            refPos = data[left] < data[right] ? left : right; //获取子结点中较小的值的位置 
        } else { //右边的结点有越界 
            refValue = data[left];
            refPos = left;
        }
        if (value > refValue) {
            swap(pos, refPos);
        } else {
            break;
        }
        
        pos = refPos;
        left = pos * 2 + 1;
        right = left + 1; 
        value = data[pos];
    }
}

void heap_pop() {
    if(dataIndex <= 0) {
        return;
    }
    
    data[0] = data[dataIndex - 1]; // 1.把尾部的值放到头部
    dataIndex--;
    fix_down(); // 2.小根堆,向下调整
}

void preOrder(int pos) {
    if(pos < 0 || pos > dataIndex-1) {
        return;
    }
    printf("%d ", data[pos]);
    preOrder(pos * 2 + 1);
    preOrder(pos * 2 + 2);
}

void main() {
    heap_insert(15);
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_insert(8);
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_insert(10);
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_insert(4);
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_insert(1);
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_insert(7);
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_insert(30);
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_pop();
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_pop();
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_pop();
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_pop();
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_pop();
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_pop();
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_pop();
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
    heap_pop();
    printf("preOrder: ");
    preOrder(0);
    printf("\n");
}
上一篇下一篇

猜你喜欢

热点阅读