一:概念什么的,可以参考小小的算法之旅这本书。
二:c语言demo例程(最小堆)
//main.c
#include "BH.h"
int main(int argc, char **argv)
{
int k[9] = {
1,3,2,6,5,7,8,9,10};
int a[10] = {
1,3,2,6,5,7,8,9,10,0};
int b[9] = {
7,1,3,10,5,2,8,9,6};
upAdjust(a, sizeof(a)/sizeof(int));
for(int i = 0;i<sizeof(a)/sizeof(int);i++)
{
printf("a[%d] = %d\n", i , a[i]);
}
k[0] = k[8];
downAdjust(k,0,sizeof(k)/sizeof(int));
for(int i = 0;i<sizeof(k)/sizeof(int);i++)
{
printf("k[%d] = %d\n", i , k[i]);
}
buildHeap(b,sizeof(b)/sizeof(int));
for(int i = 0;i<sizeof(b)/sizeof(int);i++)
{
printf("b[%d] = %d\n", i , b[i]);
}
return 0;
}
/*
二叉堆:
基本操作:
(1)插入:从最后一个位置开始插入,然后调整
(2)删除:从第一个节点删除,然后抽取最后一个节点填补第一个节点的值,然后下沉
(3)调整:平衡调整
本质上是一种完全二叉树。
最小堆:最小堆的任何一个父节点的值都小于或等于它的左右孩子节点的值。
最大堆:最大堆的任何一个父节点的值都大于或等于它的左右孩子节点的值。
*/
//BH.c
#include<stdio.h>
#include<stdlib.h>
/***************************************************************
* @file BH.c
* @brief 上调
* @author txj
* @version v1
* @date 2021/3/14
**************************************************************/
void upAdjust(int arry[],int length)
{
/*新插入的节点*/
int childIndex = length - 1;
/*新插入节点的父节点*/
int parentIndex = (childIndex - 1)/2;
/*先保存新插入的节点*/
int temp = arry[childIndex];
/**/
while(childIndex > 0 && temp < arry[parentIndex])
{
/*把父节点的值给孩子节点,但是父节点的值还是原来的值*/
arry[childIndex] = arry[parentIndex];
/*更新孩子节点和父节点的Index*/
childIndex = parentIndex;
parentIndex = (parentIndex - 1)/2;
}
/*退出循环时才会进行节点的更新*/
arry[childIndex] = temp;
return;
}
/***************************************************************
* @file BH.c
* @brief 下浮
* @author txj
* @version v1
* @date 2021/3/14
**************************************************************/
void downAdjust(int arry[], int parentIndex, int length)
{
/*temp保存要删除的节点*/
int temp = arry[parentIndex];//1
/*暂时定为到右孩子*/
int childIndex = 2 * parentIndex + 1; //1
while(childIndex < length)
{
/*如果右孩子存在,并且右孩子比左孩子小,那么就定位到右孩子*/
if(childIndex + 1 < length && arry[childIndex + 1] < arry[childIndex])
{
childIndex++;
}
/*把要删除的节点和它的孩子节点比较,如果孩子节点大于将要
删除的节点,那么就无需交换,直接退出循环即可*/
if(temp <= arry[childIndex])
{
break;
}
/*找到要下沉的位置*/
arry[parentIndex] = arry[childIndex];
parentIndex = childIndex;
childIndex = 2 * childIndex + 1;
}
arry[parentIndex] = temp;
return;
}
/***************************************************************
* @file BH.c
* @brief 构建一个二叉堆(本质是下沉的过程)
* @author txj
* @version v1
* @date 2021/3/14
**************************************************************/
void buildHeap(int arry[],int length)
{
/*从最后一个非叶子节点开始下沉*/
for(int i = (length - 2)/2 ; i >= 0; i--)
{
downAdjust(arry, i, length);
}
return;
}
//BH.h
#ifndef _BH_H_
#define _BH_H_
#include<stdio.h>
#include<stdlib.h>
typedef struct array
{
int a[10];
int length;
}tarray;
void upAdjust(int arry[],int length);
void downAdjust(int arry[], int parentIndex, int length);
void buildHeap(int arry[],int length);
#endif