二叉树是非常基本的数据结构,它的结构体可以写为如下:
struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
构建了一棵树后我们就可以开始遍历这棵树了,树的遍历可以分为先序遍历、中序遍历、后序遍历和层次遍历。
先序遍历
操作过程:
如果一个二叉树为空,则什么都不做,否则:
1)访问根节点
2)先序遍历左子树
3)先序遍历右子树
算法描述(递归版)
void PreOrderTraverse(TreeNode * root){ //将访问的节点的值放入vector中
if(root==NULL) return;
visit(root);
if(root->left) PreOrderTraverse(root->left);
if(root->right) PreOrderTraverse(root->right);
}
非递归版
vector<int> PreOrderTraverse(TreeNode* root) {
stack <TreeNode *> sta;
vector<int> res;
if(root==NULL) return res;
TreeNode * temp;
sta.push(root);
while(!sta.empty()){
temp = sta.top();
res.push_back(temp->val);
sta.pop();
if(temp->right) sta.push(temp->right);
if(temp->left) sta.push(temp->left);
}
return res;
}
中序遍历
操作过程:
如果一个二叉树为空,则什么都不做,否则:
1)中序遍历左子树
2)访问根节点
3)中序遍历右子树
算法描述(递归版)
void InOrderTraverse(TreeNode * root){
if(root==NULL) return;
if(root->left) InOrderTraverse(root->left);
visit(root);
if(root->right) InOrderTraverse(root->right);
}
非递归版
vector<int> InOrderTraverse(TreeNode* root) {
stack<TreeNode*> sta;
vector<int> res;
TreeNode* rt = root;
while(rt || sta.size()){
while(rt){ //节点有左孩子就一直压入栈中
sta.push(rt);
rt=rt->left;
}
rt=sta.top();
sta.pop();
res.push_back(rt->val);
rt=rt->right;
}
return res;
}
后序遍历
操作过程:
如果一个二叉树为空,则什么都不做,否则:
1)后序遍历左子树
2)后序遍历右子树
3)访问根节点
算法描述(递归版)
void PostOrderTraverse(TreeNode * root){
if(root==NULL) return;
if(root->left) PostOrderTraverse(root->left);
if(root->right) PostOrderTraverse(root->right);
visit(root);
}
非递归版:
vector<int> PostOrderTraverse(TreeNode * root{
vector <int> res;
if(root == NULL) return res;
stack <TreeNode *> stack1 ;
stack <TreeNode *> stack2;
TreeNode * p =NULL;
stack1.push(root) ;
while(!stack1.empty()){
p = stack1.top();
stack1.pop();
stack2.push(p) ; //这里和先序遍历的区别,输出改为入stack2
/*注意下面这两个if语句和先序遍历的区别,左、右孩子的入栈顺序相反*/
if(p->left ) stack1.push(p->left ) ;
if(p->right) stack1.push(p->right) ;
}
while (!stack2.empty()){
res.push_back(stack2.top()->val);
stack2.pop();
}
return res;
}
层次遍历需要用到队列
void level(TreeNode *root){
queue<TreeNode *> que;
if (root==NULL) return que;
que.push(root);
while (!que.empty()){
visit(que.front()); // 访问当前节点 ,应对不同的题有不同的访问操作
if(que.front()->left) que.push(que.front()->left);
if(que.front()->right) que.push(que.front()->right);
que.pop();
}
}