堆通常是一个可以被看做一棵树的数组对象。
/****************************************************************************
*Project:Heap 堆
*Author:Rise
*Note:这里是小根堆
*堆通常是一个可以被看做一棵树的数组对象。
*****************************************************************************/
#include<stdlib.h>
#include<stdio.h>
#include<memory.h>
#include<malloc.h>
#include<time.h>
#include<math.h>
#include<stdbool.h>
#include<vld.h>
#pragma pack(4) //4字节对齐
#define INIT_SIZE 20
typedef struct heap
{
int* _array;
int index;
size_t size;
}*pheap, minheap, maxheap,heap;
void addMinHeap(minheap* mh, int data);
void CreateMinHeap(minheap* mh)
{
mh->size = INIT_SIZE;
mh->_array = (int*)malloc(sizeof(int) * mh->size);
memset(mh->_array, 0, _msize(mh->_array));
mh->index = -1;
}
void FreeMinHeap(minheap* mh)
{
if (mh->_array != NULL)
{
free(mh->_array);
mh->_array = NULL;
}
mh->size = 0;
mh->index = -1;
}
inline bool isFullMinHeap(minheap* mh)
{
return mh->index == mh->size - 1;
}
bool isEmptyMinHeap(minheap* mh)
{
return mh->index == -1;//-1表示空,没有写入数据
}
int getFloorMinHeap(minheap* mh)
{
return (int)floor(log2(mh->index)) + 1;
}
int bottomMaxMinHeap(minheap* mh)
{
return (int)pow(2, (double)(getFloorMinHeap(mh) - 1));
}
int findData(minheap* mh,const int data)
{
for (int i = 0; i <= mh->index; ++i)
{
if (data == mh->_array[i])
return i;
}
return -1;
}
void adjustup(minheap* mh,const int index)
{
int cur = index;
int dad = (cur - 1) / 2;
int temp = mh->_array[cur];
while (cur > 0)
{
if (mh->_array[dad] < mh->_array[cur])
break;
mh->_array[cur] = mh->_array[dad];
cur = dad;
dad = (cur - 1) / 2;
}
mh->_array[cur] = temp;
}
void adjustdown(minheap* mh,const int index)
{
int cur = index;
int son = cur * 2 + 1;//左子节点
int temp = mh->_array[cur];
while(son<mh->index)
{
//son<mh->index确保有右子节点;mh->_array[son]>mh->_array[son+1]选左右节点中最小的
if (son<mh->index && mh->_array[son]>mh->_array[son + 1])
son++;
if (temp < mh->_array[son])
break;
else
{
mh->_array[cur] = mh->_array[son];
cur = son;
son = cur * 2 + 1;
}
}
mh->_array[cur] = temp;
}
void addMinHeap(minheap* mh, int data)
{
if (mh->size > mh->index + 1)
{
mh->_array[mh->index + 1] = data;
mh->index++;
adjustup(mh, mh->index);
}
else
{
int* tmp = mh->_array;
mh->_array = (int*)malloc(sizeof(int) * (mh->size + 3)); //随着数据越来越大,很容易分配失败;
memcpy(mh->_array, tmp, _msize(tmp));
free(tmp);
mh->_array[mh->index + 1] = data;
mh->index++;
adjustup(mh, mh->index);
}
}
bool deleteMinHeap(minheap* mh,const int data)
{
if (mh->index < 0)
return false;
int index = findData(mh, data);
if (index == -1)
return false;
//与最后一个元素交换,再删最后一个元素
mh->_array[index] = mh->_array[mh->index];
mh->_array[mh->index] = 0;
mh->index--;
adjustdown(mh, index);
return true;
}
void printHeapArray(heap h)
{
for (int i = 0; i <= h.index; i++)
{
printf("%d ", h._array[i]);
}
printf("\n");
}
/********************堆排序************************************************/
void printArray(int h[], int count)
{
for (int i = 0; i < count; i++)
{
printf("%d ", h[i]);
}
printf("\n");
}
void adjustupMinHeap(int h[], int count, int index)
{
int tmp = h[index];
int cur = index;
int dad = (cur - 1) / 2;
while(cur > 0 )
{
if (h[dad] < h[cur])
break;
h[cur] = h[dad];
cur = dad;
dad = (cur - 1) / 2;
}
h[cur] = tmp;
}
void SortMinHeap(int h[], int count)
{
for (int i = 0; i < count; i++)
{
adjustupMinHeap(h, i + 1, i);
}
}
/**************************************************************************/
int main()
{
int arr[] = { 10,20,30,41,45,24,38,39,50,88,86,101 };
minheap mp;
CreateMinHeap(&mp);
for (int i = 0; i < 12; i++)
addMinHeap(&mp, arr[i]);
printHeapArray(mp);
//deleteMinHeap(&mp, 10);
//printHeapArray(mp);
FreeMinHeap(&mp);
printArray(arr, 12);
SortMinHeap(arr, 12);
printArray(arr, 12);
return 0;
}