先序遍历:
void PreOrder(Node* t)
{
if(t)//不为空
{
cout<<t->m_value<<" ";
PreOrder(t->m_left);
PreOrder(t->m_right);
}
}
中序遍历:
void InOrder(Node* t)
{
if(t)
{
InOrder(r->m_left);
cout<<t->m-value<<" ";
InOrder(r->m_right);
}
}
后序遍历:
void PostOrder(Node* t)
{
if(t)
{
PostOrder(t->m_left);
PosrOrder(t->m_right);
cout<<t->m_value<<" ";
}
}
非递归层序遍历:
需要用队列,因为队列先进先出,按从上到下、从左到右的顺序入队列也就可以按此顺序出队列。
1、先入整棵树的第一个结点也就是根,队列不为空就用一个临时结点先保存队首元素,然后出队列,同时输出相应的值;
2、之后判断临时结点(也就是刚刚出队的结点)的左右结点,不为空就按左右顺序入队;
3、重复1,2直至队列为空。
注意:如果用栈,如果栈顶元素出栈时按左右顺序入栈,出栈时就不符合从左到右的层序遍历;如果按右左顺序入栈,下一次出栈时虽然左结点先出来了,但是此时要入该结点的左右结点,所以和该结点同层的右结点就会被压在下面,所以说不能用栈。
void LevelOrder(Node* t)
{
queue<Node*> qu;
Node* front = NULL;
if (t)
{
qu.push(t);
while(!qu.empty())
{
front = qu.front();
qu.pop();
cout << front->m_value << " ";
if (front->m_left != NULL)
{
qu.push(front->m_left);
}
if (front->m_right != NULL)
{
qu.push(front->m_right);
}
}
}
}
非递归先序遍历:
需要使用栈,由于栈是先进后出,而先序遍历要求根左右,所以先入根结点,再出根结点,同时按右左顺序压入孩子结点。
1、先入整棵树的第一个结点也就是根,栈不为空就用一个临时结点先保存栈顶元素,然后出栈,同时输出相应的值;
2、之后判断临时结点(也就是刚刚出队的结点)的左右结点,不为空就按右左顺序入栈;
3、重复1,2直至栈为空。
注意:如果用队列,A出队后入BE,那么最终出队的顺序和层序一样;如果入B不入E,出B后入CD,但是最后找不到E;所以说不能用队列。
void PreOrder_1(Node* t)
{
stack<Node*> st;
if (t)
{
st.push(t);
while (!st.empty())
{
Node* pre=st.top();
st.pop();
cout << pre->m_value << " ";
if (pre->m_right != NULL)
{
st.push(pre->m_right);
}
if (pre->m_left != NULL)
{
st.push(pre->m_left);
}
}
}
}
非递归中序遍历:
需要用栈。
1、先将根结点及以下的所有左子树入栈;
2、判断栈是否为空,如果不为空获得栈顶出栈,同时用临时结点p 记住当前结点的右孩子并且入栈,如果没有就往上回归;
3、查看当前p是否有左子树,如果有,则继续执行1,2,3步骤,直到p为空或者栈为空为止。
注意:如果是一个根结点然后只有右孩子的单边情况,那么就是一直在做出栈保存右结点,入右结点,再出栈保存右结点,入右结点......
void InOrder_1(Node* t)
{
if (t != NULL)
{
stack<Node*> ss;
Node* p = t;
Node* top = NULL;
while (p || !ss.empty())//如果仅仅只是栈非空,那么没有遍历右子树
{
while (p != NULL)
{
ss.push(p);
p = p->m_left;
}
if (!ss.empty())
{
top = ss.top();
ss.pop();
cout << top->m_value << " ";
p = top->m_right; //当前结点遍历完,记住右子树
}
}
}
}
非递归后续遍历:
需要用栈。
1、先将当前结点入栈,如果有左右孩子就一直按右左顺序入栈;
2、出栈分两种情况:
2.1、如果当前结点没有左右孩子直接出栈;
2.2、如果当前结点有左右孩子但是已经出栈,则出栈。
所以需要一个结点pre 来保存刚刚出栈的结点,然后在出下一个结点时比较pre 是否是自己的孩子结点,是才能出栈。
void PostOrder_1(Node* t)
{
if (t != NULL)
{
stack<Node*> ss;
Node* top = NULL, * pre = NULL;
ss.push(t);
while (!ss.empty())
{
top = ss.top();
if (top->m_left == NULL && top->m_right == NULL ||
pre != NULL && top->m_left == pre || pre != NULL && top->m_right == pre)
{
ss.pop();
cout << top->m_value << " ";
pre = top;
}
else
{
if (top->m_right != NULL)
ss.push(top->m_right);
if (top->m_left != NULL)
ss.push(top->m_left);
}
}
}
}