/*testheap.c*/
#include <stdio.h>
#include <time.h>
#include <assert.h>

#include "heap.h"

#define ARRAY_MAX_LEN 1000
int disp_heap(struct heap_root *root)
{
        int i;
        printf("disp_heap:");
        for(i = 0; i < root->offset; i++)
        {
                printf("%d ",(root->root + i)->d);
        }
        printf("\n");
}

int compare(int x, int y)
{
        return (x-y);
}

int main()
{
        srand((unsigned int)time(NULL));
        int a[ARRAY_MAX_LEN];
        int a_len = sizeof(a)/sizeof(int);
        int it = 10000;
        while(it--)
        {
                int aj = a_len;
                while(aj--)
                {
                        a[aj]=rand()%ARRAY_MAX_LEN;
                }

                struct heap_root *h_root;
                h_root = make_heap(ARRAY_MAX_LEN,compare);
                int i;
                int w_len = rand()%ARRAY_MAX_LEN ;
                for(i = 0; i < w_len; i++)
                {
                        struct heap_node node;
                        node.d = a[i];
                        push_heap(h_root, node);
                }

                //printf("\nh_root->offset=%d\n", h_root->offset);
                //disp_heap(h_root);
                //printf("\n");
                int pre = ARRAY_MAX_LEN + 10;
                for(i = 0; i < w_len; i++)
                {
                        struct heap_node node;
                        assert(pre >= node.d);
                        pop_heap(h_root, &node);
                        pre = node.d;
                        //printf("%d ", node.d);
                        //disp_heap(h_root);
                }
                //printf("\n");
                destroy_heap(h_root);

        }

        return 0;
}
/*heap.h*/
#include <stdlib.h>
#include <stdio.h>
typedef int elem_t;

struct heap_node{
        elem_t d;
};

struct heap_root{
        struct heap_node *root;
        int offset;
        int (*compare)();
        int heap_max;
};
struct heap_root* make_heap(int size, int (*compare_fun)());
int destroy_heap(struct heap_root *heap_head);

int push_heap(struct heap_root *root, struct heap_node node);
int pop_heap(struct heap_root *root, struct heap_node *node);
/*heap.c*/
#include "heap.h"


struct heap_root* make_heap(int size, int (*compare_fun)())
{
        if(NULL == compare_fun || size <= 0)
        {
                return NULL;
        }

        struct heap_node *root = calloc(size, sizeof(struct heap_node));
        struct heap_root *heap_head = calloc(1, sizeof(struct heap_root));

        heap_head->root = root;
        heap_head->offset = 0;
        heap_head->compare = compare_fun;
        heap_head->heap_max = size;

        return heap_head;
}


int destroy_heap(struct heap_root *heap_head)
{
        free(heap_head->root);
        free(heap_head);
        return 0;
}

int push_heap(struct heap_root *root, struct heap_node node)
{
        if(root->offset >= root->heap_max )
        {
                printf("ERROR:Out Of Bound\n");
                return -1;
        }

        struct heap_node *top = root->root;

        struct heap_node *cur = top + root->offset;
        *cur = node;

        int cur_i = root->offset;
        int par_i = (cur_i - 1)/2;
        int ret;
        while(cur_i > 0)
        {
                ret = compare(top[cur_i], top[par_i]) > 0;
                if(ret > 0)
                {
                        swap(&top[cur_i], &top[par_i]);
                }
                cur_i = par_i;
                par_i = (cur_i - 1)/2;
        }

        root->offset++;

        //printf("push:top=%d\n",top->d);
        return 0;

}


int pop_heap(struct heap_root *root, struct heap_node *node)
{
        if(root->offset <= 0 || root->offset >= root->heap_max)
        {
                printf("ERROR:Out Of Bound\n");
                return -1;
        }
        struct heap_node *top = root->root;
        *node = *top;
        root->offset--;

        *top = *(top + root->offset );
        //printf("__node.d=%d\n", node->d);
        int ret;

        int cur_i = 0;//current node index
        int lch_i = cur_i*2 + 1;//left child node index
        int rch_i = (cur_i + 1)*2;//right child node index
        int index;
        while(lch_i < root->offset)
        {
                //printf("cur:%d lch_i:%d\n", cur_i, lch_i);
                index = lch_i;
                if(rch_i < root->offset)
                {
                        ret = compare(top[rch_i], top[lch_i]);
                        if(ret > 0)
                        {
                                index = rch_i;
                        }
                }

                ret = compare(top[index], top[cur_i]);
                if(ret > 0)
                {
                        swap(&top[cur_i], &top[index]);
                        cur_i = index;
                }
                else
                {
                        break;
                }

                lch_i = cur_i*2 + 1;//left child node index
                rch_i = (cur_i + 1)*2;//right child node index
        }

        return 0;
}


int swap(struct heap_node *x, struct heap_node *y)
{
        struct heap_node tmp = *x;
        *x = *y;
        *y = tmp;

        return 0;
}

Makefile
CC=gcc
Cflag=-Wall -g
Obj=testheap.o heap.o

testheap:$(Obj)
        $(CC) -o testheap $(Obj) $(Cflag)
.c.o:
        $(CC) -c $< $(Cflag)
相關文章
相關標籤/搜索