用最笨的方法,實現的最短路徑算法(C語言)

使用最笨的方法實現,遞歸遍歷的方式,有待持續的優化。附件中有原始代碼和測試用例。

#include "commondef.h"
#include "depthsearch.h"
#ifdef __cplusplus
extern "C"
{
#endif
void SearchDestNode
(
    const MapEdge       *pstEdgeList,
          UINT32         ulEdgeCnt,
          NodeName      *pstNodeList,
          UINT32         ulDepth,
          NodeDistance   preDistance,
    const NodeName      *pNodeTo,
          NodeDistance  *pMinDistance
)
{
    UINT32          ulLoop;
    const MapEdge  *pstEdge;
    NodeName       *pTempNodeName;
    UINT32          isFromAdd;
    UINT32          isToAdd;
    /* 如果上一層處理的最後節點,是結束節點,立即返回 */
    if (pstNodeList[ulDepth - 1] == *pNodeTo)
    {
        if (preDistance < *pMinDistance)
        {
            *pMinDistance = preDistance;
        }           
        return;
    }
    for (ulLoop = 0; ulLoop < ulEdgeCnt; ulLoop++)
    {
        pstEdge = pstEdgeList + ulLoop;
        /* 已經結束,立即返回 */
        if ((pstEdge->nodeFrom == *pNodeTo && pstNodeList[ulDepth - 1] == pstEdge->nodeTo)
            || (pstEdge->nodeTo == *pNodeTo && pstNodeList[ulDepth - 1] == pstEdge->nodeFrom))
        {
            if (preDistance + pstEdge->nodeDistance < *pMinDistance)
            {
                *pMinDistance = preDistance + pstEdge->nodeDistance;
            }           
            return;
        }
        /* 當前節點起始位置都在路徑中存在,跳過此節點 */
        pTempNodeName = pstNodeList;
        isFromAdd = BOOL_FALSE;
        isToAdd = BOOL_FALSE;
        while (pTempNodeName < pstNodeList + ulDepth)
        {
            if (*pTempNodeName == pstEdge->nodeFrom)
            {
                isFromAdd = BOOL_TRUE;
            }
            if (*pTempNodeName == pstEdge->nodeTo)
            {
                isToAdd = BOOL_TRUE;
            }
            pTempNodeName++;
        }
        /* 當銜接上一層節點,並且下一個節點不在鏈表中,繼續拼接 */
        if (isFromAdd ^ isToAdd)
        {
            if (pstNodeList[ulDepth - 1] == pstEdge->nodeFrom && !isToAdd)
            {
                pstNodeList[ulDepth] = pstEdge->nodeTo;
                SearchDestNode(pstEdgeList, ulEdgeCnt, pstNodeList,
                        ulDepth + 1, preDistance + pstEdge->nodeDistance, pNodeTo, pMinDistance);
            }
            else if (pstNodeList[ulDepth - 1] == pstEdge->nodeTo && !isFromAdd)
            {
                pstNodeList[ulDepth] = pstEdge->nodeFrom;
                SearchDestNode(pstEdgeList, ulEdgeCnt, pstNodeList, ulDepth + 1,
                    preDistance + pstEdge->nodeDistance, pNodeTo, pMinDistance);
            }
        }
    }   
}
NodeDistance ApiCalMinDistance
(
    const MapEdge           *pstEdgeList,
          UINT32             ulEdgeCnt,
    const NodeName          *pNodeFrom,
    const NodeName          *pNodeTo,
    const SysCallBackFun    *pstCallback
)
{
    NodeName *ptNodeList;
    NodeDistance minDistance = MAX_DISTANCE;
    UINT32 ulLoop;
    
    ptNodeList = (NodeName *)pstCallback->pfMemAlloc(sizeof(NodeName) * ( 2 * ulEdgeCnt - 1));
    if (ptNodeList == NULL_PTR)
    {
        return minDistance;
    }
    if (*pNodeFrom == *pNodeTo)
    {
        for (ulLoop = 0; ulLoop < ulEdgeCnt; ulLoop++)
        {
            if ((pstEdgeList[ulLoop].nodeFrom == *pNodeFrom)
                || (pstEdgeList[ulLoop].nodeTo == *pNodeFrom))
            {
                return MIN_DISTANCE;
            }
        }
    }
    else
    {
        for (ulLoop = 0; ulLoop < ulEdgeCnt; ulLoop++)
        {
            if (pstEdgeList[ulLoop].nodeFrom == *pNodeFrom)
            { 
                ptNodeList[0] = *pNodeFrom;
                ptNodeList[1] = pstEdgeList[ulLoop].nodeTo;
                SearchDestNode(pstEdgeList, ulEdgeCnt, ptNodeList, 2, pstEdgeList[ulLoop].nodeDistance, pNodeTo, &minDistance);
            }
            else if (pstEdgeList[ulLoop].nodeTo == *pNodeFrom)
            {          
                ptNodeList[0] = *pNodeFrom;
                ptNodeList[1] = pstEdgeList[ulLoop].nodeFrom;
                SearchDestNode(pstEdgeList, ulEdgeCnt, ptNodeList, 2, pstEdgeList[ulLoop].nodeDistance, pNodeTo, &minDistance);
            }
        }       
    }
      
    pstCallback->pfMemFree(ptNodeList);   
    return minDistance;
}
#ifdef __cplusplus
}
#endif


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章