文章目录
遍历
遍历
即:遍历每个元素。
for遍历只会遍历每个元素一次。
二叉树遍历每个元素则会依次遍历三次。
分别叫
第一次进入/前序/通过父节点进入此节点
第二次进入/中序/即通过左节点进入此节点
第三次进入/后序/即通过右节点进入此节点
通过左右节点进入则代表左右子树都遍历完。
中序遍历/节点的中序
void traveres(TreeNode* root){
if(!root)
return;
traveres(root->left);
cout << root->val << endl;
traveres(root->right);
}
中序是指节点在其左树遍历完后所做的操作。
节点在中序的时候做cout。则每个节点都在中序的时候做cout。
则traveres(root->left);
左树的节点都在中序的时候cout,即左树的中序。
所以,在节点的中序前(cout前)也是有内容的,即其左树的中序。
但并非只有左树的中序。在左树的中序前还有。即
节点与根节点路径上的节点中序。但并非每个节点都有中序。而是要具体判断。
如13中序前(cout前),有
13左树中序,6+6左树的中序,无3,1+1左树的中序。
判断方式:
是否遍历完节点左树。即节点中序。而左树的结果也就是左树中序。
前序遍历-节点的前序
void traveres(TreeNode* root){
if(!root)
return;
cout << root->val << endl;
traveres(root->left);
traveres(root->right);
}
节点在前序指在第一次进节点时做cout。
同理,traveres(root->left);
指左树的前序。
同理,`在节点的前序前还有。即
节点与根节点路径上的节点前序。但此时路径上的节点则必有其前序。
如14,有7的前序,有3的前序,有1的前序。
后序遍历-节点的后序
void traveres(TreeNode* root){
if(!root)
return;
traveres(root->left);
traveres(root->right);
cout << root->val << endl;
}
后序指节点在其子树遍历完后做cout。
同理,traveres(root->left);
指左树的后序。traveres(root->right);
指右树的后序。
同理,在节点子树后序前还有。依旧
节点与根节点路径上的节点后序。但此时路径上的节点必无。而是有其子树后序。
如15,则有14的后序,有6的后序,有2的后序。
三序综合
vector<int> A;
vector<int> B;
vector<int> C;
void traveres(TreeNode* root){
if(!root)
return;
A.push_back(root->val);
traveres(root->left);
B.push_back(root->val);
traveres(root->right);
C.push_back(root->val);
}
任意一个节点
如13
13-Apush前/前序前
此时
前序结果:
6+6左树的前序,3,1+1左树的前序。路径节点必有。
中序结果:
6+6左树的中序,无3,1+1左树的中序。具体判断。
后序结果:
12的后序,2的后序。路径的节点必无。
13-Bpush前/中序前
此时
前序结果:
13+13左树的前序,6+6左树的前序,3,1+1左树的前序。路径节点必有。
中序结果:
13左树的中序,6+6左树的中序,无3,1+1左树的中序。具体判断。
后序结果:
13左树的后序,12的后序,2的后序。路径的节点必无。
13-Cpush前/后序前
此时
前序结果:
整个13的前序,6+6左树的前序,3,1+1左树的前序。路径节点必有。
中序结果:
整个13的中序,6+6左树的中序,无3,1+1左树的中序。具体判断。
后序结果:
13左树的后序+13右树的后序,12的后序,2的后序。路径的节点必无。
两序重叠
示例一
void traveres(TreeNode* root){
if(!root)
return;
A.push_back(root->val);
traveres(root->left);
A.pop_back(root->val);
traveres(root->right);
}
节点在前序的时候入A,在中序的时候清空A。
那么traveres(root->left);
也就是左树在中序的时候清空A
13前序前
此时,节点与跟节点的路径
13:还没有入A
6:已经进入右树。故无6
3:正在遍历左树。故有3
1:已经进入右树。故无1
故A有3。
13中序前
此时,节点与跟节点的路径
13:还没有pop A
6:已经遍历完左树
3:正在遍历左树
1:已经遍历完左树
故A有3,13。
示例二
vector<int> A;
void traveres(TreeNode* root){
if(!root)
return;
A.push_back(root->val);
traveres(root->left);
traveres(root->right);
A.pop_back(root->val);
}
节点在前序的时候入A,在后序的时候清空A
那么traveres(root->left);
也就是左树在后序的时候清空A。
同理,右树也在后序的时候清空A。
13前序前
此时,节点与跟节点的路径
13:还没有入A
6:正在遍历右树
3:正在遍历左树
1:正在遍历右树
故A有1,3,6。
13后序前
此时,节点与跟节点的路径
13:还没有pop A
6:正在遍历右树
3:正在遍历左树
1:正在遍历右树
故A有1,3,6,13。
示例三
vector<int> A;
void traveres(TreeNode* root){
if(!root)
return;
traveres(root->left);
A.push_back(root->val);
traveres(root->right);
A.pop_back(root->val);
}
节点在中序的时候入A,在后序的时候清空A。
那么traveres(root->left);
左树在中序的时候入A,后序的时候清空A。
同理,右树也在中序的时候入A,后序的时候清空A。
13中序前
此时,节点与跟节点的路径
13:遍历完左树。还没push。
6:正在遍历右树
3:正在遍历左树
1:正在遍历右树
故A有1,6。
13后序前
此时,节点与跟节点的路径
13:遍历完子树。还没pop。
6:正在遍历右树
3:正在遍历左树
1:正在遍历右树
故A有1,6,13。
let allRoot = TreeNode.create([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,31]);