对于一棵二叉树一般有三种遍历方式,先序遍历(preOrder)、中序遍历(inOrder)、后序遍历(postOrder)。
同时这里还介绍了二叉树的 层次遍历(levelOrder)
每种遍历都有递归的实现和非递归的实现。
1、preOrder
对每个节点进行遍历,并将right节点push到一个stack中
//递归实现 void preOrder1(BinTree *root) //递归前序遍历 { if(root!=NULL) { cout<<root->data<<" "; preOrder1(root->lchild); preOrder1(root->rchild); } } //非递归 void preOrder2(BinTree *root) //非递归前序遍历 { stack<BinTree*> s; BinTree *p=root; while(p!=NULL||!s.empty()) { while(p!=NULL) { cout<<p->data<<" "; s.push(p); p=p->lchild; } if(!s.empty()) { p=s.top(); s.pop(); p=p->rchild; } } }
2、inOrder
通过一个stack存储遍历的中心节点,知道最左边的节点,然后对stack进行pop操作。
//递归实现 void inOrder1(BinTree *root) //递归中序遍历 { if(root!=NULL) { inOrder1(root->lchild); cout<<root->data<<" "; inOrder1(root->rchild); } } //非递归实现 void inOrder2(BinTree *root) //非递归中序遍历 { stack<BinTree*> s; BinTree *p=root; while(p!=NULL||!s.empty()) { while(p!=NULL) { s.push(p); p=p->lchild; } if(!s.empty()) { p=s.top(); cout<<p->data<<" "; s.pop(); p=p->rchild; } } }
3、postOrder
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
//递归
void postOrder1(BinTree *root) //递归后序遍历
{
if(root!=NULL)
{
postOrder1(root->lchild);
postOrder1(root->rchild);
cout<<root->data<<" ";
}
}
//非递归
void postOrder(BinTree *root) //非递归后序遍历 { stack<BinTree*> s; BinTree *cur; //当前结点 BinTree *pre=NULL; //前一次访问的结点 s.push(root); while(!s.empty()) { cur=s.top(); if((cur->lchild==NULL&&cur->rchild==NULL)|| (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild))) { cout<<cur->data<<" "; //如果当前结点没有孩子结点或者孩子节点都已被访问过 s.pop(); pre=cur; } else { if(cur->rchild!=NULL) s.push(cur->rchild); if(cur->lchild!=NULL) s.push(cur->lchild); } } }
4、层次遍历
一次从左到右输出一颗二叉树的 每一层元素。
定义两个queue,将其中一个queue中每个元素的左右节点一次push进另一个queue中,直到该队列为空。
然后访问另一queue执行同样的操作。
//leetcode中遍历的方法 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { queue<TreeNode *> in1,in2; vector<vector<int>> re; if (root == NULL) return re; in1.push(root); while (!in1.empty()||!in2.empty()){ vector<int> temp; if (!in1.empty()){ while (!in1.empty()){ TreeNode *p = in1.front(); in1.pop(); temp.push_back(p->val); if (p->left != NULL) in2.push(p->left); if (p->right!= NULL) in2.push(p->right); } } else { while (!in2.empty()){ TreeNode *p = in2.front(); in2.pop(); temp.push_back(p->val); if (p->left != NULL) in1.push(p->left); if (p->right != NULL) in1.push(p->right); } } re.push_back(temp); } return re; } };