使用最笨的方法实现,递归遍历的方式,有待持续的优化。附件中有原始代码和测试用例。#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