#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
typedef struct Heap {
int arr[30];
int size;
} Heap;
void HeapInit(Heap *Hp, int arr[], int size)
{
assert(Hp);
memset(Hp->arr, 0, sizeof(int)*size);
memcpy(Hp->arr, arr, sizeof(int)*size);
Hp->size = size;
}
void Swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void AdjustDown(Heap *Hp, int parent)
{
int left = parent*2 + 1;
int right = parent*2 + 2;
int maxChild;
if(left > Hp->size) {
return;
}
//找出大孩子
maxChild = left;
if(right < Hp->size && Hp->arr[left] < Hp->arr[right]) {
maxChild = right;
}
//判断大孩子和双亲的大小关系
if(Hp->arr[parent] < Hp->arr[maxChild])
Swap(&Hp->arr[parent], &Hp->arr[maxChild]);
AdjustDown(Hp, maxChild);
}
void AdjustUp(Heap *Hp, int child)
{
//有问题,为什么把while换成递归就会出错
int parent = (child - 1)/2;
while(1) {
parent = (child - 1)/2;
//已经调整到根了
if(child == 0) {
break;
}
//已经调整到满足堆了
if(Hp->arr[parent] > Hp->arr[child]) {
break;
}
//走到这里表示孩子比双亲大,需要调整
Swap(Hp->arr + parent, Hp->arr + child);
//调整完成之后需要调整下一个结点
child = parent;
}
}
void HeapCreat(Heap *Hp, int size)
{
assert(Hp);
if(size <= 1) {
return;
}
int i;
for(i = (size - 1 - 1)/2 ; i >= 0 ; i--) {
AdjustDown(Hp, i);
}
}
void HeapInsert(Heap *Hp, int data)
{
assert(Hp);
//插入只能在最后一个结点后面插
//但是插入之后不满足堆,需要重新调整
Hp->arr[Hp->size++] = data;
AdjustUp(Hp, Hp->size-1);
}
void HeapDelTop(Heap *Hp)
{
assert(Hp);
Swap(&Hp->arr[0], &Hp->arr[Hp->size - 1]);
Hp->size--;
int i;
for(i = Hp->size - 1 ; i >= 0 ; i--) {
AdjustDown(Hp, i);
}
}
AdjustDownArray(int arr[], int size, int parent)
{
int left = parent * 2 + 1;
int right = parent * 2 + 2;
int max;
while(1) {
left = parent * 2 + 1;
right = parent * 2 + 2;
if(left > size) {
break;
}
max = left;
if(right < size && arr[left] < arr[right]) {
max = right;
}
if(arr[parent] < arr[max]) {
Swap(arr + parent, arr + max);
}
//AdjustDownArray(arr, size, max);
parent = max;
}
}
//在数组中找到最小的k个数
void TopK(int arr[], int size, int k)
{
int *TopArr = (int *)malloc(sizeof(int)*k);
int i = 0;
for(i = 0 ; i < k ; i++) {
TopArr[i] = arr[i];
}
for(i = (k - 2)/2 ; k >= 0 ; i--) {
AdjustDownArray(TopArr, k, i);
}
for(i = k ; i < size ; i++) {
if(arr[i] > TopArr[0])
AdjustDownArray(TopArr, k, 0);
}
for (i = 0 ; i < k ; i++) {
printf("%d ",TopArr[i]);
}
}
void HeapPrint(Heap *Hp)
{
assert(Hp);
int i = 0;
for(i = 0 ; i < Hp->size ; i++) {
printf("%d " , Hp->arr[i]) ;
}
printf("\n");
}
void HeapPop(Heap *Hp)
{
assert(Hp);
if(Hp->size < 1) {
return;
}
Hp->arr[0] = Hp->arr[1];
Hp->size--;
AdjustDown(Hp, 0);
}
int main()
{
int arr[] = {21, 45, 34, 18, 64, 75, 59, 33};
Heap Hp;
HeapInit(&Hp, arr, sizeof(arr)/sizeof(int));
HeapCreat(&Hp, sizeof(arr)/sizeof(int));
HeapPrint(&Hp);
HeapInsert(&Hp, 44);
HeapPrint(&Hp);
HeapDelTop(&Hp);
HeapPrint(&Hp);
//TopK(arr, sizeof(arr)/sizeof(int), 3);
HeapPop(&Hp);
HeapPrint(&Hp);
return 0;
}