二叉树的前中后序遍历(递归,非递归),时间复杂度为N,空间复杂度为N
思路:
1)二叉树的三种递归遍历,只是递归遍历树的时候,打印的时机不同,第一次遍历结点的时候打印,为先序遍历。第二次为中序,第三次为后序。(在树的递归的时候,每个结点都会遍历三次)。
2)二叉树的非递归遍历,用栈来辅助这三次遍历的过程
先序遍历非递归版本:
思路:把根节点压入栈中,此时就是栈顶元素,然后,弹出就打印,依次压入弹出的根节点的右孩子,左孩子。然后重复上面的过程。这个程序终止的条件是,栈变为了空。
void preOrderUNRecur(Node *root )//这里的root代表的是栈最上面的元素。
{
if(root != NULL)
{
stack <Node*> st;
st.push( root );
while( !st.empty() )
{
root = st.top();
cout<<root->val<<" ";
st.pop();
if(root->right !=NULL)
{
st.push(root->right );
}
if(root->left !=NULL)
{
st.push(root->left );
}
}
}
中序遍历非递归版本:
思路:充分利用两个空孩子的空档,输出打印左结点,根节点,神奇
void midOrderUNRecur(Node *root )
{
if(root != NULL)
{
stack <Node*> st;
while( !st.empty() || root!=NULL)
{
if(root!=NULL)
{
st.push(root);
root=root->left;
}
else//充分利用两个空孩子
{
root=st.top();
cout<<root->val<<" ";st.pop();
root=root->right;
}
}
}
}
后序遍历非递归版本:
思路:用两个栈实现,保证第二个栈,装入根节点,再装入右结点,左结点。。。整个过程完全在模拟递归的使用套路。
void postOrderUNRecur(Node *head )
{
if(head!=NULL)
{
stack<Node * > s1;
stack<Node * > s2;
s1.push(head);
while( !s1.empty() )
{
head = s1.top(); s1.pop();
s2.push(head);
if( head->left!=NULL)
{
s1.push(head->left);
}
if( head->right!=NULL)
{
s1.push(head->right);
}
}
while(!s2.empty())
{
cout<<s2.top()->val<<" ";
s2.pop();
}
}
}
总共的三个过程,去感受其神奇之处。做研究应该关注其本身(by左神),基本的东西就应该熟练掌握。