堆是一种比较复杂的数据结构,也就是通常所说的完全二叉树,分为最大堆和最小堆,定义如下:
- 最大堆:根结点的键值是所有堆结点键值中最大者的堆。

- 最小堆:根结点的键值是所有堆结点键值中最小者的堆。

而最大-最小堆集结了最大堆和最小堆的优点,这也是其名字的由来。 最大-最小堆是最大层和最小层交替出现的二叉树,即最大层结点的儿子属于最小层,最小层结点的儿子属于最大层。 以最大(小)层结n点为根结点的子树保有最大(小)堆性质:根结点的键值为该子树结点键值中最大(小)项。
下面看看AMPS中对堆的操作:
AMPS_Heap.h
#ifndef __HEADER_AMPS_HEAP_H
#define __HEADER_AMPS_HEAP_H
#ifdef __cplusplus
extern "C" {
#endif
#include "AMPS_Defines.h"
#include "AMPS_LinkList.h"
#define HEAP_SIZE 1009
typedef struct _HeapNode t_HeapNode;
typedef struct _Heap t_Heap;
typedef int(*AMPS_HeapNodeDeleteCallback)(AMPS_HANDLE r_hAMPS_HANDLE, void* r_pvHeapNode);
/*堆结点*/
struct _HeapNode
{
long lKey; /*结点的key值,从1开始,相当于此结点的索引*/
void* pvDataValue; /*结点内容*/
};
struct _Heap
{
int nIndex; // last node / number of current nodes (complete-binary-tree array representation ...)
int nNoOfAllocatedNodes; // number of allocated nodes in ->pnode array
t_HeapNode* poNodeArray; // the node-array
AMPS_HeapNodeDeleteCallback pfNodeDeleteCallback;
};
void* Heap_Init(void* r_pvAMPSContext, int r_nSizeofHeap, AMPS_HeapNodeDeleteCallback r_pfNodeDeleteCallback);
void Heap_Cleanup (void* r_pvAMPSContext, void* r_pvHeap);
int Heap_InsertMax (void* r_pvAMPSContext, void* r_pvHeap, void* r_pvData, long rlKey);
int Heap_InsertMin (void* r_pvAMPSContext, void* r_pvHeap, void* r_pvData, long rlKey);
int Heap_GetMaxNode (void* r_pvAMPSContext, void* r_pvHeap, void** r_pvvExtractedNode);
int Heap_GetMinNode (void* r_pvAMPSContext, void* r_pvHeap, void** r_pvvExtractedNode);
int Heap_DeleteMaxNode (void* r_pvAMPSContext, void* r_pvHeap);
int Heap_DeleteMinNode (void* r_pvAMPSContext, void* r_pvHeap);
int Heap_RemoveNodeMax (void* r_pvAMPSContext, void* r_pvHeap, long rlKey);
int Heap_RemoveNodeMin (void* r_pvAMPSContext, void* r_pvHeap, long rlKey);
int Heap_UpdateNodeMax (void* r_pvAMPSContext, void* r_pvHeap, long rlKey, long rlNewKey, void* r_pvData);
int Heap_UpdateNodeMin (void* r_pvAMPSContext, void* r_pvHeap, long rlKey, long rlNewKey, void* r_pvData);
int Heap_UpdateNodeMaxKey (void* r_pvAMPSContext, void* r_pvHeap, long rlKey, long rlNewKey);
int Heap_UpdateNodeMinKey (void* r_pvAMPSContext, void* r_pvHeap, long rlKey, long rlNewKey);
int Heap_SearchMax (void* r_pvAMPSContext, void* r_pvHeap, int r_nIndex, long rlKey);
int Heap_SearchMin (void* r_pvAMPSContext, void* r_pvHeap, int r_nIndex, long rlKey);
int Heap_HeapifyMax (void* r_pvAMPSContext, void* r_pvHeap, int r_nStartIndex);
int Heap_HeapifyMin (void* r_pvAMPSContext, void* r_pvHeap, int r_nStartIndex);
int Heap_BuildHeapMax (void* r_pvAMPSContext, void* r_pvHeap);
int Heap_BuildHeapMin (void* r_pvAMPSContext, void* r_pvHeap);
int Heap_HeapSortMax (void* r_pvAMPSContext, void* r_pvHeap);
int Heap_HeapSortMin (void* r_pvAMPSContext, void* r_pvHeap);
int Heap_HeapPrint (void* r_pvAMPSContext, void* r_pvHeap);
#ifdef __cplusplus
}
#endif
#endif //__HEADER_AMPS_HEAP_H
AMPS_Heap.c
/*****************************************************************
文件名称: AMPS_Heap.c
功能描述: 堆操作API函数(最大堆和最小堆)
*****************************************************************/
#include "AMPS_Core.h"
#include "AMPS_Defines.h"
#include "AMPS_MemMgt.h"
#include "AMPS_Heap.h"
#include "AMPS_Hash.h"
#include "AMPS_LinkList.h"
/*****************************************************************
函数名称: Heap_SwapElements
功能描述: 交换堆中两个指定的结点
入参::
void* r_pvHeap 堆
int nIndexA 待交换的结点A索引
int nIndexB 待交换的结点B索引
出参:
void* r_pvHeap 堆
返回值:
void
*****************************************************************/
void Heap_SwapElements (void* r_pvHeap, int nIndexA, int nIndexB)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
t_HeapNode oTemp;
if (nIndexA == nIndexB)
{
return;
}
oTemp.lKey = poHeap->poNodeArray[nIndexA - 1].lKey;
oTemp.pvDataValue = poHeap->poNodeArray[nIndexA - 1].pvDataValue;
poHeap->poNodeArray[nIndexA - 1].lKey = poHeap->poNodeArray[nIndexB - 1].lKey;
poHeap->poNodeArray[nIndexA - 1].pvDataValue = poHeap->poNodeArray[nIndexB - 1].pvDataValue;
poHeap->poNodeArray[nIndexB - 1].lKey = oTemp.lKey;
poHeap->poNodeArray[nIndexB - 1].pvDataValue = oTemp.pvDataValue;
}
/*****************************************************************
函数名称: Heap_GetParentIndex
功能描述: 获取指定结点的父结点索引
入参::
int rIndex 指定的结点索引
出参:
NA
返回值:
long
*****************************************************************/
long Heap_GetParentIndex (int rIndex)
{
/*函数floor的意思是获取小于或者等于指定表达式的最大整数*/
return ((long)floor(rIndex/2));
}
/*****************************************************************
函数名称: Heap_GetLeftIndex
功能描述: 获取指定结点的左侧子结点
入参::
int rIndex 指定的结点索引
出参:
NA
返回值:
long
*****************************************************************/
long Heap_GetLeftIndex (int rIndex)
{
return 2*rIndex;
}
/*****************************************************************
函数名称: Heap_GetRightIndex
功能描述: 获取指定结点的右侧子结点
入参::
int rIndex 指定的结点索引
出参:
NA
返回值:
long
*****************************************************************/
long Heap_GetRightIndex (int rIndex)
{
return 2*rIndex + 1;
}
/*****************************************************************
函数名称: Heap_Init
功能描述: 堆的初始化函数
入参::
void* r_pvAMPSContext AMPS应用上下文
int r_nSizeofHeap 堆的总大小(即结点总个数)
AMPS_HeapNodeDeleteCallback r_pfNodeDeleteCallback 结点操作函数
出参:
void * 堆指针
返回值:
void*
*****************************************************************/
void* Heap_Init(void* r_pvAMPSContext, int r_nSizeofHeap, AMPS_HeapNodeDeleteCallback r_pfNodeDeleteCallback)
{
t_Heap* poHeap = NULL;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*堆结构分配内存*/
poHeap = AMPS_InternalMalloc(sizeof(t_Heap));
if (NULL == poHeap)
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for *r_ppvHeap.\n");
return NULL;
}
/*结点数组分配内存*/
poHeap->poNodeArray = AMPS_InternalMalloc(sizeof(t_HeapNode) * r_nSizeofHeap);
if (NULL == poHeap->poNodeArray)
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalMalloc failed for poHeap->poNodeArray.\n");
return NULL;
}
/*堆成员初始化*/
poHeap->nNoOfAllocatedNodes = r_nSizeofHeap;
poHeap->nIndex = 0;
poHeap->pfNodeDeleteCallback = r_pfNodeDeleteCallback;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return poHeap;
}
/*****************************************************************
函数名称: Heap_Cleanup
功能描述: 堆的销毁函数
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
出参:
void * 堆指针
返回值:
void
*****************************************************************/
void Heap_Cleanup(void* r_pvAMPSContext, void* r_pvHeap)
{
t_Heap* poHeap = r_pvHeap;
int nCount = 0;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*使用注册的结点处理回调函数先处理各结点*/
if(NULL != poHeap->pfNodeDeleteCallback)
{
for(nCount = 0; nCount < poHeap->nIndex; nCount ++ )
{
poHeap->pfNodeDeleteCallback(r_pvAMPSContext, poHeap->poNodeArray[nCount].pvDataValue);
}
}
/*释放节点数据内存*/
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalFree called for poHeap->poNodeArray.\n");
AMPS_InternalFree(poHeap->poNodeArray);
/*释放堆内存*/
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "AMPS_InternalFree called for poHeap.\n");
AMPS_InternalFree(poHeap);
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
}
/*****************************************************************
函数名称: Heap_InsertMax
功能描述: 大根堆插入结点
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
void* r_pvData 待插入的数据
long rlKey 待插入的key值
出参:
void * 堆指针
返回值:
int
*****************************************************************/
int Heap_InsertMax (void* r_pvAMPSContext, void* r_pvHeap, void* r_pvData, long rlKey)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
int nCount;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*堆已满,删除最大结点,再插入*/
if (poHeap->nIndex >= poHeap->nNoOfAllocatedNodes)
{
// out of space
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "heap full.\n");
Heap_DeleteMaxNode (r_pvAMPSContext,r_pvHeap);
return Heap_InsertMax(r_pvAMPSContext,r_pvHeap,r_pvData,rlKey);
}
/*记数加1*/
nCount = poHeap->nIndex++;
/*从最低层结点开始,如果有结点小于当前待插入结点,此节点下沉,最终保证
所有子二插树根结点比其子结点大*/
while (nCount != 0 && rlKey > poHeap->poNodeArray[nCount/2].lKey)
{
poHeap->poNodeArray[nCount] = poHeap->poNodeArray[nCount/2];
nCount /= 2;
}
/*赋值*/
poHeap->poNodeArray[nCount].lKey = rlKey;
poHeap->poNodeArray[nCount].pvDataValue = r_pvData;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return nCount;
}
/*****************************************************************
函数名称: Heap_InsertMin
功能描述: 小根堆插入结点
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
void* r_pvData 待插入的数据
long rlKey 待插入的key值
出参:
void * 堆指针
返回值:
int
*****************************************************************/
int Heap_InsertMin (void* r_pvAMPSContext, void* r_pvHeap, void* r_pvData, long rlKey)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
int nCount;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*堆已满,删除最小的结点,插入新的*/
if (poHeap->nIndex >= poHeap->nNoOfAllocatedNodes)
{
// out of space
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "heap full.\n");
Heap_DeleteMinNode (r_pvAMPSContext,r_pvHeap);
return Heap_InsertMin(r_pvAMPSContext,r_pvHeap,r_pvData,rlKey);
}
nCount = poHeap->nIndex++;
/*从最低层结点开始,如果有结点大于当前待插入结点,此节点下沉,最终保证
所有子二插树根结点比其子结点小*/
while (nCount != 0 && rlKey < poHeap->poNodeArray[nCount/2].lKey)
{
poHeap->poNodeArray[nCount] = poHeap->poNodeArray[nCount/2];
nCount /= 2;
}
poHeap->poNodeArray[nCount].lKey = rlKey;
poHeap->poNodeArray[nCount].pvDataValue = r_pvData;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return nCount;
}
/*****************************************************************
函数名称: Heap_GetMaxNode
功能描述: 获取大根堆根结点
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
void** r_pvvExtractedNode
出参:
void** r_pvvExtractedNode 根结点
返回值:
int
*****************************************************************/
int Heap_GetMaxNode (void* r_pvAMPSContext, void* r_pvHeap, void** r_pvvExtractedNode)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
if (0 == poHeap->nIndex)
{
// empty heap
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "empty heap.\n");
return AMPS_ERROR_FAILURE;
}
*r_pvvExtractedNode = (void*)(&poHeap->poNodeArray[0]);
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_GetMinNode
功能描述: 获取小根堆根结点
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
void** r_pvvExtractedNode
出参:
void** r_pvvExtractedNode 根结点
返回值:
int
*****************************************************************/
int Heap_GetMinNode (void* r_pvAMPSContext, void* r_pvHeap, void** r_pvvExtractedNode)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
if (0 == poHeap->nIndex)
{
// empty heap
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "empty heap.\n");
return AMPS_ERROR_FAILURE;
}
*r_pvvExtractedNode = (void*)(&poHeap->poNodeArray[0]);
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_DeleteMaxNode
功能描述: 删除堆中的最大结点(大根堆)
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
出参:
NA
返回值:
int
*****************************************************************/
int Heap_DeleteMaxNode (void* r_pvAMPSContext, void* r_pvHeap)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*删除最大结点(注:我觉得这里的最大结点应该是根结点poHeap->poNodeArray[0].lKey,为什么写为根结点的
左侧子结点,这个没有想通)*/
if (AMPS_SUCCESS != Heap_RemoveNodeMax (r_pvAMPSContext,r_pvHeap, poHeap->poNodeArray[1].lKey))
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "HeapRemoveNodeMax failed.\n");
return AMPS_ERROR_FAILURE;
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_DeleteMinNode
功能描述: 删除堆中的最小结点(小根堆)
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
出参:
NA
返回值:
int
*****************************************************************/
int Heap_DeleteMinNode (void* r_pvAMPSContext, void* r_pvHeap)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*删除最小结点(注:我觉得这里的最小结点应该是根结点poHeap->poNodeArray[0].lKey,为什么写为根结点的
左侧子结点,这个没有想通)*/
if (AMPS_SUCCESS != Heap_RemoveNodeMin (r_pvAMPSContext, r_pvHeap, poHeap->poNodeArray[1].lKey))
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "HeapRemoveNodeMin failed.\n");
return AMPS_ERROR_FAILURE;
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_SearchMax
功能描述: 在大根堆中查找指定的结点索引
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
int r_nStartIndex 开始查找的位置
long rlKey 待查找结点的key值
出参:
NA
返回值:
int
*****************************************************************/
//Divide and conquer approach
int Heap_SearchMax (void* r_pvAMPSContext, void* r_pvHeap, int r_nStartIndex, long rlKey)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
if ((r_nStartIndex > poHeap->nIndex)||(r_nStartIndex < 1))
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Invalid index.\n");
return AMPS_ERROR_FAILURE;
}
/*这种永远找不到*/
if (rlKey > poHeap->poNodeArray[r_nStartIndex - 1].lKey)
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Invalid key.\n");
return AMPS_ERROR_FAILURE;
}
if (rlKey == poHeap->poNodeArray[r_nStartIndex - 1].lKey)
{
return r_nStartIndex;
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
/*分左右子树进行递归,最后取最大的index,因为至少有一个返回AMPS_ERROR_FAILURE,即-1*/
return AMPS_Max(Heap_SearchMax (r_pvAMPSContext, poHeap, (2 * r_nStartIndex), rlKey), Heap_SearchMax(r_pvAMPSContext, poHeap, (2 * r_nStartIndex) + 1, rlKey));
}
/*****************************************************************
函数名称: Heap_SearchMin
功能描述: 在小根堆中查找指定的结点索引
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
int r_nStartIndex 开始查找的位置
long rlKey 待查找结点的key值
出参:
NA
返回值:
int
*****************************************************************/
int Heap_SearchMin (void* r_pvAMPSContext, void* r_pvHeap, int r_nStartIndex, long rlKey)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "Searching for Key = %ld.\n", rlKey);
if ((r_nStartIndex > poHeap->nIndex)||(r_nStartIndex < 1))
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Invalid index.\n");
return AMPS_ERROR_FAILURE;
}
if (rlKey < poHeap->poNodeArray[r_nStartIndex - 1].lKey)
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_DEBUG, "compared with key = %ld.\n", poHeap->poNodeArray[r_nStartIndex - 1].lKey);
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Invalid key.\n");
return AMPS_ERROR_FAILURE;
}
if (rlKey == poHeap->poNodeArray[r_nStartIndex - 1].lKey)
{
return r_nStartIndex;
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
/*在win32环境下,-1小于0或正整数,这块没有问题*/
// Since HeapSearchMin can return -1 (AMPS_ERROR_FAILURE) a direct call AMPS_Min won't be correct
{
int nA = Heap_SearchMin (r_pvAMPSContext, poHeap, (2 * r_nStartIndex), rlKey);
int nB = Heap_SearchMin(r_pvAMPSContext, poHeap, (2 * r_nStartIndex) + 1, rlKey);
if (nA < 0)
{
if (nB > 0)
{
return nB; // A is negative B is positive
}
else
{
return AMPS_ERROR_FAILURE; // Both are negative
}
}
else if (nB < 0) // A is positive
{
return nA;
}
else // Both are positive
{
return AMPS_Min (nA, nB);
}
}
}
/*****************************************************************
函数名称: Heap_RemoveNodeMin
功能描述: 在小根堆中删除指定的结点
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
long rlKey 待删除结点的key值
出参:
NA
返回值:
int
*****************************************************************/
int Heap_RemoveNodeMin (void* r_pvAMPSContext, void* r_pvHeap, long rlKey)
{
int nNodePosition = 0;
t_Heap* poHeap = (t_Heap*)r_pvHeap;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*找到指定的结点*/
nNodePosition = Heap_SearchMin(r_pvAMPSContext, poHeap, 1, rlKey);
if (AMPS_ERROR_FAILURE == nNodePosition)
{
return AMPS_SUCCESS;
}
/*删除前处理结点*/
if (NULL != poHeap->pfNodeDeleteCallback)
{
if (AMPS_SUCCESS != poHeap->pfNodeDeleteCallback (r_pvAMPSContext, poHeap->poNodeArray[nNodePosition - 1].pvDataValue))
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "poHeap->pfNodeDeleteCallback failed.\n");
return AMPS_ERROR_FAILURE;
}
}
poHeap->poNodeArray[nNodePosition - 1].lKey = 0;
poHeap->poNodeArray[nNodePosition - 1].pvDataValue = NULL;
/*如果不为最后一个结点,与最后的结点交换*/
if (nNodePosition != poHeap->nIndex) //last element has been removed
{
Heap_SwapElements (poHeap, nNodePosition, poHeap->nIndex); // is valid
}
/*删除最后一个结点*/
poHeap->nIndex--;
/*删除后,重新建立树*/
if (nNodePosition > 1)
{
// Determine if a child or parent
if ((Heap_GetRightIndex(nNodePosition) > poHeap->nIndex) && (Heap_GetRightIndex(nNodePosition) > poHeap->nIndex))
{
// its a child
Heap_HeapifyMin(r_pvAMPSContext, poHeap, (int)floor(nNodePosition/2));
//BuildHeapMin(r_pvAMPSContext, poHeap); // is more expensive
}
else
{
// its a parent
Heap_HeapifyMin(r_pvAMPSContext, poHeap, (int)floor(nNodePosition));
//BuildHeapMin(r_pvAMPSContext, poHeap); // is more expensive
}
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_RemoveNodeMin
功能描述: 在大根堆中删除指定的结点
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
long rlKey 待删除结点的key值
出参:
NA
返回值:
int
*****************************************************************/
int Heap_RemoveNodeMax (void* r_pvAMPSContext, void* r_pvHeap, long rlKey)
{
int nNodePosition = 0;
t_Heap* poHeap = (t_Heap*)r_pvHeap;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
nNodePosition = Heap_SearchMax(r_pvAMPSContext, poHeap, 1, rlKey);
if (poHeap->pfNodeDeleteCallback)
{
if (AMPS_SUCCESS != poHeap->pfNodeDeleteCallback (r_pvAMPSContext, &poHeap->poNodeArray[nNodePosition - 1].pvDataValue))
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "poHeap->pfNodeDeleteCallback failed.\n");
return AMPS_ERROR_FAILURE;
}
}
poHeap->poNodeArray[nNodePosition - 1].lKey = 0;
poHeap->poNodeArray[nNodePosition - 1].pvDataValue = NULL;
if (nNodePosition != poHeap->nIndex) //last element has been removed
{
Heap_SwapElements (poHeap, nNodePosition, poHeap->nIndex); // is valid
}
poHeap->nIndex--;
if (nNodePosition > 1)
{
// Determine if a child or parent
if ((Heap_GetRightIndex(nNodePosition) > poHeap->nIndex) && (Heap_GetRightIndex(nNodePosition) > poHeap->nIndex))
{
// its a child
Heap_HeapifyMax(r_pvAMPSContext, poHeap, (int)floor(nNodePosition/2));
//BuildHeapMax(r_pvAMPSContext, poHeap); // is more expensive
}
else
{
// its a parent
Heap_HeapifyMax(r_pvAMPSContext, poHeap, (int)floor(nNodePosition));
//BuildHeapMax(r_pvAMPSContext, poHeap); // is more expensive
}
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_UpdateNodeMax
功能描述: 在大根堆中更新指定的结点
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
long rlKey 待更新结点的key值
long rlNewKey 新的key值
void* r_pvData 结点数据
出参:
NA
返回值:
int
*****************************************************************/
int Heap_UpdateNodeMax (void* r_pvAMPSContext, void* r_pvHeap, long rlKey, long rlNewKey, void* r_pvData)
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
/*先删除后插入*/
Heap_RemoveNodeMax (r_pvAMPSContext,r_pvHeap,rlKey);
Heap_InsertMax (r_pvAMPSContext,r_pvHeap, r_pvData,rlNewKey);
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_UpdateNodeMin
功能描述: 在小根堆中更新指定的结点
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
long rlKey 待更新结点的key值
long rlNewKey 新的key值
void* r_pvData 结点数据
出参:
NA
返回值:
int
*****************************************************************/
int Heap_UpdateNodeMin (void* r_pvAMPSContext, void* r_pvHeap, long rlKey, long rlNewKey, void* r_pvData)
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
Heap_RemoveNodeMin (r_pvAMPSContext,r_pvHeap,rlKey);
Heap_InsertMin (r_pvAMPSContext,r_pvHeap, r_pvData,rlNewKey);
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_UpdateNodeMinKey
功能描述: 在小根堆中更新指定的结点key值
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
long rlKey 待更新结点的key值
long rlNewKey 新的key值
出参:
NA
返回值:
int
*****************************************************************/
int Heap_UpdateNodeMinKey (void* r_pvAMPSContext, void* r_pvHeap, long rlKey, long rlNewKey)
{
int nNodePosition = 0;
t_Heap* poHeap = (t_Heap*)r_pvHeap;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
nNodePosition = Heap_SearchMin(r_pvAMPSContext, poHeap, 1, rlKey);
if (AMPS_ERROR_FAILURE == nNodePosition)
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Heap_SearchMin failed.\n");
return AMPS_ERROR_FAILURE;
}
poHeap->poNodeArray[nNodePosition - 1].lKey = rlNewKey;
/*更新后重新建立小根堆*/
Heap_BuildHeapMin(r_pvAMPSContext,r_pvHeap);
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_UpdateNodeMaxKey
功能描述: 在大根堆中更新指定的结点key值
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
long rlKey 待更新结点的key值
long rlNewKey 新的key值
出参:
NA
返回值:
int
*****************************************************************/
int Heap_UpdateNodeMaxKey (void* r_pvAMPSContext, void* r_pvHeap, long rlKey, long rlNewKey)
{
int nNodePosition = 0;
t_Heap* poHeap = (t_Heap*)r_pvHeap;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
nNodePosition = Heap_SearchMax(r_pvAMPSContext, poHeap, 1, rlKey);
if (AMPS_ERROR_FAILURE == nNodePosition)
{
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_ERROR, "Heap_SearchMax failed.\n");
return AMPS_ERROR_FAILURE;
}
poHeap->poNodeArray[nNodePosition - 1].lKey = rlNewKey;
/*更新后,重新建立大根堆*/
Heap_BuildHeapMax(r_pvAMPSContext,r_pvHeap);
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_HeapifyMax
功能描述: 从指定索引开始,调整大根堆
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
int r_nStartIndex 指定位置
出参:
NA
返回值:
int
*****************************************************************/
int Heap_HeapifyMax (void* r_pvAMPSContext, void* r_pvHeap, int r_nStartIndex)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
int nLeftIndex = Heap_GetLeftIndex(r_nStartIndex);
int nRightIndex = Heap_GetRightIndex(r_nStartIndex);
int nLargestValueIndex = 0;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
if ((nLeftIndex <= poHeap->nIndex) && (poHeap->poNodeArray[nLeftIndex - 1].lKey > poHeap->poNodeArray[r_nStartIndex - 1].lKey))
{
nLargestValueIndex = nLeftIndex;
} else
{
nLargestValueIndex = r_nStartIndex ;
}
if ((nRightIndex <= poHeap->nIndex) && (poHeap->poNodeArray[nRightIndex - 1].lKey > poHeap->poNodeArray[nLargestValueIndex - 1].lKey))
{
nLargestValueIndex = nRightIndex;
}
if (nLargestValueIndex != r_nStartIndex)
{
Heap_SwapElements (r_pvHeap, r_nStartIndex, nLargestValueIndex);
Heap_HeapifyMax(r_pvAMPSContext, poHeap, nLargestValueIndex);
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_HeapifyMin
功能描述: 从指定索引开始,调整小根堆
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
int r_nStartIndex 指定位置
出参:
NA
返回值:
int
*****************************************************************/
int Heap_HeapifyMin (void* r_pvAMPSContext, void* r_pvHeap, int r_nStartIndex)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
int nLeftIndex = Heap_GetLeftIndex(r_nStartIndex);
int nRightIndex = Heap_GetRightIndex(r_nStartIndex);
int nSmallestIndex = 0;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
if ((nLeftIndex <= poHeap->nIndex) && (poHeap->poNodeArray[nLeftIndex - 1].lKey < poHeap->poNodeArray[r_nStartIndex - 1].lKey))
{
nSmallestIndex = nLeftIndex;
} else
{
nSmallestIndex = r_nStartIndex;
}
if ((nRightIndex <= poHeap->nIndex) && (poHeap->poNodeArray[nRightIndex - 1].lKey < poHeap->poNodeArray[nSmallestIndex - 1].lKey))
{
nSmallestIndex = nRightIndex;
}
if (nSmallestIndex != r_nStartIndex)
{
Heap_SwapElements (r_pvHeap, r_nStartIndex, nSmallestIndex);
Heap_HeapifyMin(r_pvAMPSContext, r_pvHeap, nSmallestIndex);
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_BuildHeapMax
功能描述: 重建大根堆
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
出参:
NA
返回值:
int
*****************************************************************/
int Heap_BuildHeapMax (void* r_pvAMPSContext, void* r_pvHeap)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
int nHeapSize = poHeap->nIndex;
int nCount = 0;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
for(nCount = (int)floor(nHeapSize/2); nCount >= 1 ;nCount--)
{
Heap_HeapifyMax(r_pvAMPSContext, poHeap, nCount);
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_BuildHeapMin
功能描述: 重建小根堆
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
出参:
NA
返回值:
int
*****************************************************************/
int Heap_BuildHeapMin (void* r_pvAMPSContext, void* r_pvHeap)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
int nHeapSize = poHeap->nIndex;
int nCount = 0;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
for(nCount = (int)floor(nHeapSize/2); nCount >= 1 ;nCount--)
{
Heap_HeapifyMin(r_pvAMPSContext, poHeap, nCount);
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_HeapPrint
功能描述: 打印堆内容
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
出参:
NA
返回值:
int
*****************************************************************/
int Heap_HeapPrint (void* r_pvAMPSContext, void* r_pvHeap)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
int nCount = 0;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
for (nCount = 0; nCount < poHeap->nIndex; nCount++)
{
printf("%d => %ld, %p\n", nCount, poHeap->poNodeArray[nCount].lKey, poHeap->poNodeArray[nCount].pvDataValue);
}
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_HeapSortMax
功能描述: 大根堆排序(最终结点从左到右依次增大)
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
出参:
NA
返回值:
int
*****************************************************************/
int Heap_HeapSortMax (void* r_pvAMPSContext, void* r_pvHeap)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
int nCount = 0;
int nTempIndex = poHeap->nIndex;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
Heap_BuildHeapMax (r_pvAMPSContext, poHeap);
for(nCount = poHeap->nIndex; nCount <= 2; nCount --)
{
Heap_SwapElements(r_pvHeap, 1, nCount);
poHeap->nIndex--;
Heap_HeapifyMax (r_pvAMPSContext,r_pvHeap, 1);
}
poHeap->nIndex = nTempIndex;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}
/*****************************************************************
函数名称: Heap_HeapSortMin
功能描述: 小根堆排序(最终结点从左到右依次减小)
入参::
void* r_pvAMPSContext AMPS应用上下文
void* r_pvHeap 待操作的堆指针
出参:
NA
返回值:
int
*****************************************************************/
int Heap_HeapSortMin (void* r_pvAMPSContext, void* r_pvHeap)
{
t_Heap* poHeap = (t_Heap*)r_pvHeap;
int nCount = 0;
int nTempIndex = poHeap->nIndex;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Entering.\n");
Heap_BuildHeapMin (r_pvAMPSContext, poHeap);
for(nCount = poHeap->nIndex; nCount <= 2; nCount --)
{
Heap_SwapElements(r_pvHeap, 1, nCount);
poHeap->nIndex--;
Heap_HeapifyMin (r_pvAMPSContext,r_pvHeap, 1);
}
poHeap->nIndex = nTempIndex;
TRACE( HEAP_TRACE_ID(r_pvAMPSContext), AMPS_TRACE_LEVEL_INFO, "Leaving.\n");
return AMPS_SUCCESS;
}