二叉堆
- 逻辑上是一个完全二叉树,但是这个二叉树每个结点的val>=子节点(大堆)或者val<=子节点(小堆)
- 物理上顺序存储空间(数组)
- 已知parent节点,左孩子为2*parent+1,右孩子为2*parent+2.已知child节点,双亲结点为(child-1)/2
定义
typedef struct Heap
{
DataType* _array;
int _capacity;
int _size;
}Heap;
创建
//向下调整堆
void AdjustDown(int array[], int size, int parent){
//完全二叉树没有左孩子一定没有右孩子
while (1){
int left = 2 * parent + 1;
if (left >= size){
return;
}
int right = 2 * parent + 2;
int min = left;
if (array[left] > array[right] && right < size)
{
min = right;
}
if (array[min]>array[parent])
return;
int t = array[min];
array[parent] = array[min];
array[min] = t;
parent = min;
}
}
void CreatHeap(int* array, int size){
//最后一个非叶子节点 = 最后一个节点的双亲节点
for (int i = ((size - 1) - 1) / 2; i >= 0; i--){
AdjustDown(array, size, i);
}
}
void InitHeap(Heap* heap, int * array, int size){
memcpy(heap->_array, array, sizeof(int)*size);
heap->_size = size;
CreatHeap(heap->_array, size);
}
尾插
void AdjustUp(int* array, int child){
while (child!=0){
int parent = (child - 1) / 2;
if (array[parent] <= array[child]){
return;
}
int t = array[child];
array[child] = array[parent];
array[parent] = t;
child = parent;
}
}
void HeapPush(Heap* heap, int v){
heap->_array[heap->_size++] = v;
AdjustUp(heap->_array, heap->_size, heap->_size - 1);
}
尾删
void HeapPop(Heap* heap){
AdjustDown(heap->_array, heap -> _size - 1, 0);
heap->_size--;
}
返回堆顶元素
int HeapTop(Heap* heap){
return heap->_array[0];
}
堆排序
排升序大堆,降序小堆
void HeapSort(int arr[],int size){
CreatHeap(arr,size);
for(int i =0;i<size-1;i++){
int t = arr[0];
arr[0] = arr[size-i-1];
arr[size-i-1] = t;//交换堆顶和堆尾
AdjustDown(arr,size-i-1,0);
}
}