#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define TYPE int
#define SWAP(a,b) {typeof(a) t=(a);(a)=(b);(b)=t;}
// 大顶堆
typedef struct Heap
{
TYPE* arr;
size_t cal;
size_t cnt;
}Heap;
Heap* create_heap(size_t cal)
{
Heap* heap = malloc(sizeof(Heap));
heap->arr = malloc(sizeof(TYPE)*cal);
heap->cal = cal;
heap->cnt = 0;
return heap;
}
// 满堆
bool full_heap(Heap* heap)
{
return heap->cnt >= heap->cal;
}
// 空堆
bool empty_heap(Heap* heap)
{
return 0 == heap->cnt;
}
// 添加
bool add_heap(Heap* heap,TYPE data)
{
if(full_heap(heap)) return false;
heap->arr[heap->cnt++] = data;
// 添加位置进行调整重新形成堆
int i = heap->cnt; //编号
while(i > 1)
{
if(data > heap->arr[i/2-1])
{
SWAP(heap->arr[i-1],heap->arr[i/2-1]);
i = i/2;
}
else
break;
}
return true;
}
// 删除 删除堆顶
bool del_heap(Heap* heap)
{
if(empty_heap(heap)) return false;
// 交换堆顶与末尾 并删除末尾
SWAP(heap->arr[0],heap->arr[heap->cnt-1]);
heap->cnt--;
// 从上往下调整
int i = 1; //编号
while(i <= heap->cnt)
{
// 有右子树
if(i*2+1 <= heap->cnt)
{
//右子树最大 交换右根
if(heap->arr[i*2] > heap->arr[i*2-1] &&
heap->arr[i*2] > heap->arr[i-1])
{
SWAP(heap->arr[i*2],heap->arr[i-1]);
i = i*2+1;
}
//左子树最大,交换左根
else if(heap->arr[i*2-1] > heap->arr[i-1])
{
SWAP(heap->arr[i*2-1],heap->arr[i-1]);
i = i*2;
}
//根最大
else
break;
}
// 没有右,有左子树
else if(i*2 <= heap->cnt)
{
// 左比根大,交换左根
if(heap->arr[i*2-1] > heap->arr[i-1])
{
SWAP(heap->arr[i*2-1],heap->arr[i-1]);
i = i*2;
}
// 左比根小,结束
else
break;
}
//没有左右
else
break;
}
return true;
}
// 遍历
void show_heap(Heap* heap)
{
for(int i=0; i<heap->cnt; i++)
{
printf("%d ",heap->arr[i]);
}
printf("\n");
}
// 堆顶
TYPE top_heap(Heap* heap)
{
return heap->arr[0];
}
// 堆排序 顺序实现
void sort_heap(int* arr,int len)
{
// 把数组调成堆结构
for(int i=1; i<=len; i++)
{
int j=i;
while(j > 1)
{
if(arr[j-1] > arr[j/2-1])
{
SWAP(arr[j-1],arr[j/2-1]);
j = j/2;
}
else
break;
}
}
// 删除堆顶,直到堆为空
while(len > 1)
{
// 交换堆顶 末尾
SWAP(arr[0],arr[len-1]);
len--;
//从上往下调整
int i = 1;
while(i <= len)
{
if(i*2+1 <= len)
{
if(arr[i*2] > arr[i*2-1]
&& arr[i*2] > arr[i-1])
{
SWAP(arr[i*2],arr[i-1]);
i = i*2+1;
}
else if(arr[i*2-1] > arr[i-1])
{
SWAP(arr[i*2-1],arr[i-1]);
i = i*2;
}
else
break;
}
else if(i*2 <= len)
{
if(arr[i*2-1] > arr[i-1])
{
SWAP(arr[i*2-1],arr[i-1]);
i = i*2;
}
else
break;
}
else
break;
}
}
}
// 从top下标 到end下标 从上往下调整成堆结构
void _sort_heap_recursion(int* arr,int top,int end)
{
if(top >= end) return;
int max = top+1; // max是左右根中最大值的编号
int l = max*2;
int r = max*2+1;
if(l-1 <= end && arr[l-1] > arr[max-1])
{
// 有左子树,且左子树大于max的值,更新max
max = l;
}
if(r-1 <= end && arr[r-1] > arr[max-1])
{
// 有右子树,且右子树大于max的值,更新max
max = r;
}
if(max-1 != top)
{
// max是左右根中最大的,交换根与max
SWAP(arr[top],arr[max-1]);
_sort_heap_recursion(arr,max-1,end);
}
}
// 堆排序 递归实现
void sort_heap_recursion(int* arr,int len)
{
// 把数组调成堆结构
for(int i=2; i<=len; i++)
{
int j=i;
while(j > 1)
{
if(arr[j-1] > arr[j/2-1])
{
SWAP(arr[j-1],arr[j/2-1]);
j = j/2;
}
else
break;
}
}
for(int i=len-1; i>0; i--)
{
SWAP(arr[0],arr[i]);
_sort_heap_recursion(arr,0,i-1);
}
}
void show_arr(int* arr,int len)
{
for(int i=0; i<len; i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
int main(int argc,const char* argv[])
{
int arr[10] = {};
for(int i=0; i<10; i++)
{
arr[i] = rand()%100;
}
sort_heap_recursion(arr,10);
show_arr(arr,10);
/*
Heap* heap = create_heap(20);
for(int i=0; i<10; i++)
{
add_heap(heap,rand()%100);
}
show_heap(heap);
add_heap(heap,99);
show_heap(heap);
while(!empty_heap(heap))
{
printf("%d \n",top_heap(heap));
del_heap(heap);
}
*/
}