AMPS:堆源码解读
来源:互联网 发布:贵州网络推广招聘 编辑:程序博客网 时间:2024/06/07 06:37
堆是一种比较复杂的数据结构,也就是通常所说的完全二叉树,分为最大堆和最小堆,定义如下:
- 最大堆:根结点的键值是所有堆结点键值中最大者的堆。
- 最小堆:根结点的键值是所有堆结点键值中最小者的堆。
而最大-最小堆集结了最大堆和最小堆的优点,这也是其名字的由来。 最大-最小堆是最大层和最小层交替出现的二叉树,即最大层结点的儿子属于最小层,最小层结点的儿子属于最大层。 以最大(小)层结n点为根结点的子树保有最大(小)堆性质:根结点的键值为该子树结点键值中最大(小)项。
下面看看AMPS中对堆的操作:
AMPS_Heap.h
#ifndef __HEADER_AMPS_HEAP_H#define __HEADER_AMPS_HEAP_H#ifdef __cplusplusextern "C" {#endif#include "AMPS_Defines.h"#include "AMPS_LinkList.h"#define HEAP_SIZE1009typedef 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 approachint 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;}
- AMPS:堆源码解读
- AMPS:队列源码解读
- AMPS:哈希表源码解读
- AMPS:Trace模块源码解读
- AMPS:字符串操作源码解读
- AMPS:MD5模块源码解读
- AMPS:AES模块源码解读
- AMPS:日志模块源码解读
- AMPS:Cache模块源码解读
- AMPS:定时器模块源码解读
- AMPS:单向链表源码解读
- AMPS:双向链表源码解读
- AMPS:数据库访问模块源码解读
- AMPS:MySQL数据库操作模块源码解读
- AMPS:Oracle数据库操作模块源码解读
- AMPS:内存管理模块源码解读(一)
- AMPS:内存管理模块源码解读(二)
- JVM源码分析之堆外内存完全解读
- 如何编写高效swing程序
- java得到系统时间
- UDP Socket(long)
- 在字符串中找到最后一个'/'并获取之前的部分
- 三层简单理解
- AMPS:堆源码解读
- 单例设计模式的两种情况
- android makefile message output
- Function Run Fun hdu1579 递推
- Firebug控制台详解
- 多线程学习记录4-Lock锁
- 线段树入门、总结 Interval Tree
- 让这里记录我的成长
- 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 03背包 HDU