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;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 玩游戏时出现窗口化怎么办 玩游戏时出现输入不支持怎么办 电脑玩游戏出现蓝屏怎么办 谷歌商店网页版进不去怎么办 谷歌商店为什么打不开怎么办 玩lol突然卡顿怎么办 手机上路由器管理页面打不开怎么办 苹果电脑开机页面密码打不开怎么办 逆战活动页面打不开怎么办 电脑玩lol网络卡怎么办 ios11.4qq闪退怎么办 ios11.3qq闪退怎么办 英雄联盟进入游戏界面黑屏怎么办 英雄联盟经常未响应怎么办 英雄联盟总是无响应怎么办 英雄联盟新客户端太卡怎么办 win10英雄联盟fps低怎么办 lol登游戏闪退怎么办 lol读取界面很慢怎么办 玩lol卡死黑屏怎么办 lol黑屏退不出来怎么办 电脑分辨率调高了黑屏怎么办 电脑设置分辨率黑屏了怎么办 分辨率调高了黑屏怎么办 电脑调分辨率黑屏了怎么办 科沃斯cr120遥控器丢了怎么办 买了kl色的钻戒怎么办 qq旋风没有蓝钻怎么办 手机桌面短信图标不见了怎么办 手机桌面qq音乐图标不见了怎么办 电脑显示器图标变大了怎么办 手机卡信号好但是网络不好怎么办 陌陌功能被限制怎么办 陌陌设备封了怎么办 荣耀v8手机开机键不灵怎么办 联通积分换的腾讯会员怎么办 小米6手机变卡了怎么办 微信绑定银行卡次数太多怎么办 银行卡绑定太多微信了怎么办 怎样给qq设密码怎么办 吃了心悦胶囊上火怎么办