二叉树的递归遍历我经常用,但很少用非递归的,特此mark一下。
下面是中序遍历的代码,具体思想就是:
把每个节点push到vector中,如果此节点的左子树没有儿子了,那么就pop掉,然后返回到上一节点。每次都要判断上一节点pLast和此时节点儿子p的关系,如果pLast==p的左儿子,那么这一次push就不能再把p的左儿子push进去,如果pLast==p的右儿子,那么继续pop。
<pre name="code" class="cpp">#include <iostream>
using namespace std;
class CTwoTree
{
public:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
CTwoTree()
{
proot = NULL;
}
void CAddNode(int m_nValue, BSTreeNode * &p)
{
if(p == NULL)
{
p = new BSTreeNode;
p->m_nValue = m_nValue;
p->m_pLeft = NULL;
p->m_pRight = NULL;
return;
}
if(m_nValue > p->m_nValue)
{
CAddNode(m_nValue, p->m_pRight);
}
else if(p->m_nValue > m_nValue)
{
CAddNode(m_nValue, p->m_pLeft);
}
}
void CAddNode(int m_nValue)
{
CAddNode(m_nValue, proot);
}
void nonRecursionLDR()
{
nonRecursionLDR(proot);
}
void mirror(BSTreeNode * p)
{
if(proot == NULL)
return;
else if(proot->m_pLeft != NULL)
{
deleter(proot->m_pLeft);
}
else if(proot->m_pRight != NULL)
{
deleter(proot->m_pRight);
}
else
{
delete proot;
}
}
void nonRecursionLDR(BSTreeNode * p)//非递归的LDR遍历
{
vector<BSTreeNode*> vTmp;
BSTreeNode* v;
BSTreeNode* vLast = NULL;
if(p != NULL)
vTmp.push_back(p);
else
return;
while(vTmp.size() != 0)
{
v = vTmp.back();
if(v->m_pRight == vLast)
{
vTmp.pop_back();
}
else if(v->m_pLeft != NULL && vLast != v->m_pLeft)
{
vTmp.push_back(v->m_pLeft);
}
else if(v->m_pRight != NULL)
{
cout << v->m_nValue << endl;
vTmp.push_back(v->m_pRight);
}
else
{
cout << v->m_nValue << endl;
vTmp.pop_back();
}
vLast = v;
}
}
void deleter(BSTreeNode *p)
{
if(p == NULL)
return;
else if(p->m_pLeft != NULL)
{
deleter(p->m_pLeft);
}
else if(p->m_pRight != NULL)
{
deleter(p->m_pRight);
}
else
{
delete p;
}
}
~CTwoTree()
{
deleter(proot);
}
private:
BSTreeNode *proot;
};
int main(int argc, char *argv[])
{
CTwoTree a;
a.CAddNode(10);
a.CAddNode(6);
a.CAddNode(4);
a.CAddNode(8);
a.CAddNode(7);
a.CAddNode(9);
a.CAddNode(14);
a.CAddNode(12);
a.CAddNode(16);
a.nonRecursionLDR();
return 0;
}