學習不易,需要堅持。
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
typedef int HPDataType ;
typedef struct Heap
{
HPDataType* array ;
int size ;
int capcity ;
}Heap ;
//向下調整
void AdjustDown(int array[], int size, int root)
{
int tmp = 0 ; //臨時變量
while(1)
{
int left = 2 * root + 1 ;
int right = 2 * root + 2 ;
int min = 0 ;
//若沒有左右孩子,直接返回
if(left >= size)
{
//越界
return ;
}
//如果存在右孩子(必有左孩子),則找值最小的孩子
if(right<size && array[right]<array[left])
{
min = right ;
}
else
{
min = left ;
}
//找到最小值後,再判斷它與根節點的值
if(array[root] <= array[min])
{
return ;
}
else
{
tmp = array[root] ;
array[root] = array[min] ;
array[min] = tmp ;
root = min ;
}
}
}
//向上調整
void AdjustUp(int array[], int size, int child)
{
int parent = 0 ; //節點的雙親
int tmp = 0 ; //臨時變量
while(child != 0)
{
parent = (child - 1 ) / 2 ;
if(array[child] > array[parent])
{
return ;
}
else
{
tmp = array[child] ;
array[child] = array[parent] ;
array[parent] = tmp ;
child = parent ;
}
}
}
//建堆,本例子建小堆
void CreatHeap(int array[], int size)
{
//從最後一個非葉子節點開始,一直調整到array[0]結束,
//最後一個非葉子節點爲最後一個節點的雙親節點
int i = 0 ;
for(i=(size-2)/2; i>=0; i--)
{
AdjustDown(array,size,i) ;
}
}
void HeapCreatHeap(Heap* heap, int array[], int size)
{
int i = 0 ;
heap->capcity = size * 2 ;
heap->size = size ;
heap->array = (int *) malloc (sizeof(int) * size) ;
for(i=0; i<size; i++)
{
heap->array[i] = array[i] ;
}
CreatHeap(heap->array, heap->size ) ;
}
//增加元素
void HeapInsert(Heap* heap, int val)
{
heap->array[heap->size] = val ;
heap->size++ ;
AdjustUp(heap->array, heap->size, heap->size - 1) ; //size-1就是 child
}
//刪除元素(只能刪除堆頂元素)
void HeapPop(Heap* heap)
{
//堆的刪除元素算法思想:將最後一個元素覆蓋原堆頂元素,再從array[0]進行調整
assert(heap->size > 0) ;
heap->array[0] = heap->array[heap->size - 1] ;
heap->size-- ;
AdjustDown(heap->array, heap->size, 0) ;
}
//返回堆頂元素值
HPDataType HeapTop(Heap* heap)
{
assert(heap->size > 0) ;
return heap->array[0] ;
}
//打印
void HeapPrint(Heap* heap, int size)
{
int i = 0 ;
for(i=0; i<heap->size; i++)
{
printf("%d ", heap->array[i]) ;
}
printf("\n") ;
}
void Test()
{
Heap heap ;
int array[] = {3, 9, 1, 7, 5, 8, 14, 13, 2, 6, 9} ;
int size = sizeof(array) / sizeof(array[0]) ;
HeapCreatHeap(&heap, array, size) ;
//打印初始的堆
printf("建好的堆爲: \n") ;
HeapPrint(&heap, size) ;
//在堆裏插入一個元素
HeapInsert(&heap, 15) ;
printf("\n插入15後:\n") ;
HeapPrint(&heap, size) ;
// 返回新堆的堆頂元素
printf("\n插入15後,堆頂元素爲: %d\n", HeapTop(&heap)) ;
//再在堆裏插入一個元素
HeapInsert(&heap, 0) ;
printf("\n再插入0後的堆爲:\n") ;
HeapPrint(&heap, size) ;
printf("插入0後,堆頂元素爲: %d\n", HeapTop(&heap)) ;
printf("\n建堆成功!\n") ;
}
int main()
{
Test() ;
printf("\n") ;
return 0 ;
}
運行結果: