先把heap的基本框架搭建起来

This commit is contained in:
建峰 2024-07-04 15:20:06 +08:00
parent 6243c46d63
commit cb580e7058
4 changed files with 124 additions and 7 deletions

View File

@ -16,5 +16,6 @@
#include "queue.h" #include "queue.h"
#include "deque.h" #include "deque.h"
#include "tree.h" #include "tree.h"
#include "heap.h"
#endif // _UNICSTL_H_ #endif // _UNICSTL_H_

View File

@ -8,6 +8,25 @@
*/ */
#include "heap.h" #include "heap.h"
static int left(int i)
{
return 2 * i + 1;
}
static int right(int i)
{
return (i << 1) + 2;
}
static int parent(int i)
{
if(i == 0)
{
return -1;
}
return (i-1) >> 1;
}
bool heap_peek(struct _heap* self, void* obj) bool heap_peek(struct _heap* self, void* obj)
{ {
assert(self != NULL); assert(self != NULL);
@ -23,15 +42,60 @@ bool heap_peek(struct _heap* self, void* obj)
return true; return true;
} }
static void heap_swap(struct _heap* self, int i, int j)
{
assert(self != NULL);
char tmp[self->_obj_size];
memmove(tmp, self->obj + i * self->_obj_size, self->_obj_size);
memmove(self->obj + i * self->_obj_size, self->obj + j * self->_obj_size, self->_obj_size);
memmove(self->obj + j * self->_obj_size, tmp, self->_obj_size);
}
static void heap_fixed(struct _heap* self, int i)
{
assert(self != NULL);
int p = 0;
while(1)
{
p = parent(i);
if(p < 0 || self->compare(self->obj + i * self->_obj_size, self->obj + p * self->_obj_size) <= 0)
{
break;
}
heap_swap(self, i, p);
i = p;
}
}
bool heap_push(struct _heap* self, void* obj) bool heap_push(struct _heap* self, void* obj)
{ {
assert(self != NULL); assert(self != NULL);
if(self->size(self) > self->_capacity)
{
return false;
}
uint32_t index = self->size(self);
memmove(self->obj + index * self->_obj_size, obj, self->_obj_size);
self->_size++;
heap_fixed(self, index);
} }
bool heap_pop(struct _heap* self, void* obj) bool heap_pop(struct _heap* self, void* obj)
{ {
assert(self != NULL); assert(self != NULL);
if(self->empty(self))
{
return false;
}
heap_swap(self, 0, self->size(self) - 1);
if(obj != NULL)
{
memmove(obj, self->obj, self->_obj_size);
}
self->_size--;
heap_fixed(self, 0);
} }
void heap_setmin(struct _heap* self, bool min_flag) void heap_setmin(struct _heap* self, bool min_flag)
@ -55,11 +119,18 @@ bool heap_empty(struct _heap* self)
bool heap_clear(struct _heap* self) bool heap_clear(struct _heap* self)
{ {
assert(self != NULL); assert(self != NULL);
self->_size = 0;
return true;
} }
void heap_destory(struct _heap* self) void heap_destory(struct _heap* self)
{ {
assert(self != NULL); assert(self != NULL);
self->clear(self);
if(self->obj)
{
free(self->obj);
}
} }
void heap_print(struct _heap* self) void heap_print(struct _heap* self)
@ -73,7 +144,7 @@ void heap_print(struct _heap* self)
for (int i = self->size(self) - 1; i >= 0; i--) for (int i = self->size(self) - 1; i >= 0; i--)
{ {
offset = self->_obj_size * i; offset = self->_obj_size * i;
obj = (char*)self->obj + offset; obj = (char *)self->obj + offset;
self->print_obj(obj); self->print_obj(obj);
} }
} }

View File

@ -49,11 +49,12 @@ int main()
printf("----- unicstl test -----\n"); printf("----- unicstl test -----\n");
// while (1) // while (1)
{ {
test_list(); // test_list();
test_stack(); // test_stack();
test_deque(); // test_deque();
test_queue(); // test_queue();
test_tree(); // test_tree();
test_heap();
} }
printf("----- unicstl ok -----\n"); printf("----- unicstl ok -----\n");

View File

@ -12,7 +12,51 @@
void test_heap_num(void) void test_heap_num(void)
{ {
uint32_t i = 0;
int data[] = { 2,1,3,4};
// int data[] = { 1,2,3,4,5,6};
// int data[] = { 5,2,3,1,7,8,6 };
// int data[] = { 5,2,3,1,7,8,6,4,9,10,12,11,15,14,13 };
int temp = 0;
uint32_t len = sizeof(data) / sizeof(data[0]);
heap_t heap = heap_new();
heap_init2(heap, sizeof(int), 64);
heap->print_obj = print_num;
heap->compare = compare_num;
printf("\n\n----- test_heap_num -----\n");
printf("----- push -----\n");
for (i = 0; i < len; i++)
{
temp = data[i];
heap->push(heap, &temp);
printf("push = ");
heap->print_obj(&temp);
printf("size = %2d : ", heap->size(heap));
heap->print(heap);
printf("\n");
}
printf("----- max -----\n");
heap->peek(heap, &temp);
heap->print_obj(&temp);
printf("\n");
printf("----- heap -----\n");
heap->clear(heap);
if(heap->empty(heap))
{
printf("----- empty -----\n");
}
printf("----- heap -----\n");
for (i = 0; i < len; i++)
{
temp = data[i];
heap->push(heap, &temp);
}
} }
void test_heap(void) void test_heap(void)