堆的实现

1.堆是一棵完全二叉树,堆有两个性质,即结构性和堆序性,堆序性指的是,对于每个结点X,它的父亲中的关键字小于或等于X的关键字。

2.完全二叉树很有规律,它可以用一个数组表示而不需要指针,对于数组中任意一个位置i上的元素,其左儿子在位置2i上,右儿子在2i+1上,它的父亲则在i/2位置上。

具体的代码实现如下:

//
//  Heap.h
//  Heap
//
//  Created by Mac on 15/12/6.
//  Copyright © 2015年 Mac. All rights reserved.
//

#ifndef Heap_h
#define Heap_h

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct _tagHeap{
    int capacity;
    int size;
    int * data;
}Heap;

//create
Heap* HeapCreate(int size);

//insert
int HeapInsert(Heap* h ,int data);

//del min
int HeapDelMin(Heap* h);

//destroy
void HeapDestroy(Heap* h);

#endif /* Heap_h */

//
//  Heap.c
//  Heap
//
//  Created by Mac on 15/12/6.
//  Copyright © 2015年 Mac. All rights reserved.
//

#include "Heap.h"

#define MIN_DATA  -9999999999

//creat 二叉堆
//类似于完全二叉树
Heap* HeapCreate(int size){
    Heap* h = (Heap*)malloc(sizeof(Heap));
    if (h == NULL) {
        return NULL;
    }
    memset(h,0,sizeof(Heap));
    
    h->capacity = size;
    h->data = (int*)malloc((size+1)*sizeof(int));
    if (h->data == NULL) {
        return NULL;
    }
    memset(h->data,0,(size+1)*sizeof(int));   //0 is pre
    h->data[0] = MIN_DATA;
    return h;
}

static bool HeapIsFull(Heap* h){
    if (h == NULL) {
        return true;
    }
    
    return h->size == h->capacity;
}

static bool HeapIsEmpty(Heap* h){
    if (h == NULL) {
        return true;
    }
    
    return h->size == 0;
}


//insert  root i   left 2*i  right 2*i+1
//要保持堆序性
int HeapInsert(Heap* h ,int data){
    if (HeapIsFull(h)) {
        return -1;
    }
    int i = 0;
    for (i = ++h->size; h->data[i/2] > data; i /=2) {  //上滤
        h->data[i] = h->data[i/2];
    }
    h->data[i] = data;
    
    return 0;
}


//del min
int HeapDelMin(Heap* h){
    if (HeapIsEmpty(h)) {
        return h->data[0];
    }
    
    int child = 0;
    int minData = h->data[1];
    int lastData = h->data[h->size--];
    
    int i = 0;
    
    for (i = 1; 2*i <= h->size; i = child) {
        child = (i << 1); // i*2;
        
        //find smaller child in left and right
        if (child != h->size && h->data[child+1] < h->data[child]) {
            child++;
        }
        
        if (h->data[child] < lastData) {
            h->data[i] = h->data[child];   //下滤
        }
        else{
            break;
        }
    }
    h->data[i] = lastData;
    
    return minData;
}


//destroy
void HeapDestroy(Heap* h){
    if (h == NULL) {
        return;
    }
    
    free(h->data);
    h->data = NULL;
    
    free(h);
    h = NULL;
}

//
//  main.c
//  Heap
//
//  Created by Mac on 15/12/6.
//  Copyright © 2015年 Mac. All rights reserved.
//

#include <stdio.h>
#include "Heap.h"

int main(int argc, const char * argv[]) {
    // insert code here...
    
    Heap* h = HeapCreate(100);
    
    HeapInsert(h, 1);
    HeapInsert(h, 2);
    HeapInsert(h, 3);
    HeapInsert(h, -1);
    
    printf("%d\n",HeapDelMin(h));
    printf("%d\n",HeapDelMin(h));
    
    printf("%d\n",h->data[1]);
    printf("%d\n",h->data[2]);
    printf("%d\n",h->data[3]);
    
//    printf("%d\n",h->size);
//    printf("%d\n",h->data[h->size--]);
//    printf("%d\n",h->data[4]);
    
    HeapDestroy(h);
    
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值