AMPS:堆源码解读

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

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

而最大-最小堆集结了最大堆和最小堆的优点,这也是其名字的由来。 最大-最小堆是最大层和最小层交替出现的二叉树,即最大层结点的儿子属于最小层,最小层结点的儿子属于最大层。 以最大(小)层结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;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值