最近看1-wire总线的DS2480芯片,里面用到了一种不使用递归来遍历二叉树叶子节点的算法。这里归纳了一下,供参考。
因为没编译过,所以细节上可能会有点问题。但算法保证是正确的。
// g_bFlag中保存的是节点的路径,数组中某一位为0,代表取这个节点的左子节点作为路径的下一个节点;
// 为1代表取右子节点作为下一个节点
char g_bFlag[MAX_DEPTH] = {0};
int g_iLastZero; // 中间变量,遍历中会用到
int g_iLastNode = 0; // 用于标记遍历是否结束
NODE* g_pRootNode = &NODE; // 设置成二叉树的根节点
int do_search(g_bFlag, MAX_DEPTH)
{
NODE* pTreeNode = g_pRootNode;
g_iLastZero = -1;
int iTempZero = -1;
if (g_iLastNode == 1)
{
return -1;
}
for (int i = 0; i < MAX_DEPTH; i++)
{
if (pTreeNode->numChildren == 0)
{
break;
}
else if (pTreeNode->numChildren == 1)
{
if (pTreeNode->pLeft)
{
pTreeNode = pTreeNode->pLeft;
g_bFlag[i] = 0;
}
else // pTreeNode->pRight != 0
{
pTreeNode = pTreeNode->pRight;
g_bFlag[i] = 1;
}
}
else // pTreeNode->numChildren == 2
{
if (i < g_iLastZero)
{
pTreeNode = (g_bFlag[i] == 0? pTreeNode->pLeft : pTreeNode->pRight);
if (g_bFlag[i] == 0)
{
iTempZero = i;
}
}
else if (i == g_iLastZero)
{
pTreeNode = pTreeNode->pRight;
g_bFlag[i] = 1;
g_iLastZero = iTempZero;
}
else // i > g_iLastZero
{
pTreeNode = pTreeNode->pLeft;
g_bFlag[i] = 0;
iTempZero = i;
}
}
}
if (iTempZero == -1)
{
g_iLastNode = 1;
}
g_iLastZero = iTempZero;
// 到这里,pTreeNode就是这次遍历得到的节点
// TODO: handle of this pTreeNode
return 0;
}