树的三遍历
树结点结构
public class TreeNode { public int data;//存放的数据 public TreeNode leftChild;//左叶子结点 public TreeNode rightChild;//右叶子结点 public TreeNode(int data){//构造函数 this.data = data; } }
然后有这么一棵树
然后根据这张图介绍遍历顺序:
前序遍历——头左右
ABC——>ABDFCGI——>ABDFECGHI——>ABDFECGHI
代码部分:
void preOrder1(TreeNode node){ if(node!=NULL) { cout<<node->data<<" "; preOrder1(node->leftChild); preOrder1(node->rightChild); } }
中序遍历——左头右
BAC——>DBFAGCI——>DBEFAGHCI——>DBEFAGHCI
代码部分:
void inOrder1(TreeNode node){ if(node!=NULL) { inOrder1(node->leftChild); cout<<node->data<<" "; inOrder1(node->rightChild); } }
后序遍历-——左右头
BCA——>DFBGICA——>DEFBHGICA——>DEFBHGICA
代码部分:
void postOrder1(TreeNode node){ if(node!=NULL) { postOrder1(node->leftChild); postOrder1(node->rightChild); cout<<node->data<<" "; } }
非递归部分
前序遍历:
void inOrder2(TreeNode node) { stack<TreeNode*> st; TreeNode *p=node; while (!st.empty()||p!=NULL) { while(p)//沿左子树到底,访问并压栈途中结点 { cout<<p->data<<" "; st.push(p); p=p->leftChild; } p=st.top(); //将结点出栈 st.pop(); p=p->rightChild; } }
中序遍历:
void inOrder2(TreeNode node) { stack<TreeNode*> st; TreeNode *p=node; while (!st.empty()||p!=NULL) { while(p)//沿左子树到底,压栈途中结点,不访问 { st.push(p); p=p->leftChild; } p=st.top(); //将结点出栈 cout<<p->data<<" ";//此时访问 st.pop(); p=p->rightChild; } }
最麻烦后序遍历:
void postOrder2(TreeNode node) { stack<TreeNode*> st; TreeNode *p=node; TreeNode *last=NULL;//最近一次访问的结点 while (!st.empty()||p!=NULL) { while(p)//沿左子树到底,压栈途中结点,不访问 { st.push(p); p=p->leftChild; } p=st.top(); //将结点出栈 //如果p没有右孩子或者其右孩子刚刚被访问过,则访问p节点,并从栈中删除 if(p->rightChild == NULL || p->rightChild == last) { cout<<p->data<<" "; st.pop(); last = p;//标记正在访问的结点 p = NULL;//这样接下来可以访问父节点 } else { p=p->rightChild; } } }