树的遍历 - 前/中/后/层 序遍历
给你二叉树的根节点 root ,返回它节点值的 前/中/后/层 序遍历。
前/中/后序遍历
递归、迭代(DFS)、Morris遍历
/**
* Definition for a binary tree node.
* 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) {}
* };
*/
递归
时间复杂度O(n)
平均空间复杂度O(logn),最坏O(n),为递归过程中隐式栈的开销
// 前序遍历 RAB
void traver_pre(vector<int> &ans, TreeNode *r) {
if(r == nullptr) return ;
ans.emplace_back(r->val); // 前序遍历 - RAB
traver_pre(ans, r->left);
// ans.emplace_back(r->val); // 中序遍历 - ARB
traver_pre(ans, r->right);
// ans.emplace_back(r->val); // 后序遍历 - ABR
}
vector<int> preorderTraversal(TreeNode *root) {
vector<int> ans;
traver_pre(ans, root);
return ans;
}
迭代 - 栈
时间复杂度O(n)
平均空间复杂度O(logn),最坏O(n),为递归过程中显式栈的开销
// 前序遍历 RAB
vector<int> preorderTraversal(TreeNode *root) {
vector<int> ans{};
stack<TreeNode*> st{};
TreeNode *p = root;
if(p) st.push(p); // 中
while(!st.empty()) {
p = st.top();
ans.emplace_back(p->val);
st.pop();
if(p->right) st.push(p->right); // 右
if(p->left) st.push(p->left); // 左
}
return ans;
}
// 中序遍历 - ARB
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ans{};
stack<TreeNode*> st{};
TreeNode *p=nullptr;
if(root) st.push(root);
while(!st.empty()) {
p = st.top();
if(p) {
st.pop();
if(p->right) st.push(p->right); // 右
st.push(p); // 中
st.push(nullptr);
if(p->left) st.push(p->left); // 左
}else {
st.pop();
ans.emplace_back(st.top()->val);
st.pop();
}
}
return ans;
}
// 后序遍历 - ABR
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ans{};
stack<TreeNode*> st{};
TreeNode *p=nullptr;
if(root) st.push(root); // 中
while(!st.empty()) {
p = st.top();
if(p) {
st.push(nullptr);
if(p->right) st.push(p->right); // 右
if(p->left) st.push(p->left); // 左
}else {
st.pop();
ans.emplace_back(st.top()->val);
st.pop();
}
}
return ans;
}
Morris 遍历
时间复杂度O(n),没有左子树的节点被访问一次,有左子树的被访问两次
空间复杂度O(1)
- 如果存在左子树,找到子树中最后访问的节点(根的左节点最右侧的节点)
- 如果其未与根建立连接,则建立连接,代表第1个位置,只与根有关,表示开始遍历其左子树
- 如果已与根建立连接,则释放连接,代表第3个位置,只与根有关,表示其左子树遍历完成
- 如果不存在左子树,开始遍历右子树
- 代表第2、4个位置,分别可表示其父节点左右节点
- 第2个位置:表示建立连接后,root向其左节点移动后,其不存在左节点的情况
- 第4个位置:表示释放连接后,root向其右节点移动后,其不存在左节点的情况
// 前序遍历 RAB
vector<int> preorderTraversal(TreeNode *root) {
vector<int> ans;
TreeNode *p;
while(root) {
if(root->left) { // 判断是否存在左子树
p = root->left;
while(p->right && p->right != root) p = p->right;
if(!p->right) { // 判断是否与根建立连接
ans.emplace_back(root->val); // 中 - 1
p->right = root;
root = root->left;
}else {
// ans.emplace_back(root->val); // 中 - 3
root = root->right;
p->right = nullptr;
}
}else { // 不存在左子树,开始遍历右子树
ans.emplace_back(root->val); // 左 - 2、右 - 4
root = root->right;
}
}
return ans;
}
// 中序遍历 ARB
vector<int> inorderTraversal(TreeNode *root) {
vector<int> ans;
TreeNode *p;
while(root) {
if(root->left) { // 存在左子树,找到子树中最后访问的节点(,将其与根建立连接)
p = root->left;
while(p->right && p->right != root) p = p->right;
if(!p->right) { // 未与根建立连接
// ans.emplace_back(root->val); // 中 - 1
p->right = root;
root = root->left;
}else {
ans.emplace_back(root->val); // 中 - 3
root = root->right;
p->right = nullptr;
}
}else { // 不存在左子树,开始遍历右子树
ans.emplace_back(root->val); // 左 - 2、右 - 4
root = root->right;
}
}
return ans;
}
// 后序遍历 RBA->ABR
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ans;
TreeNode *p;
while(root) {
if(root->right) { // 判断是否存在左子树
p = root->right;
while(p->left && p->left != root) p = p->left;
if(!p->left) { // 判断是否与根建立连接
ans.emplace_back(root->val); // 中 - 1
p->left = root;
root = root->right;
}else {
// ans.emplace_back(root->val); // 中 - 3
root = root->left;
p->left = nullptr;
}
}else { // 不存在左子树,开始遍历右子树
ans.emplace_back(root->val); // 左 - 2、右 - 4
root = root->left;
}
}
reverse(ans.begin(), ans.end());
return ans;
}
层序遍历
递归、迭代(BFS)
递归
void traver_level(vector<vector<int>> &ans, TreeNode *p, int level) {
if(p == nullptr) return;
if(ans.size() == level) ans.emplace_back(vector<int>());
ans[level].emplace_back(p->val);
traver_level(ans, p->left, level+1);
traver_level(ans, p->right, level+1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ans{};
traver_level(ans, root, 0);
return ans;
}
迭代 - 队列
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> ans{};
queue<TreeNode*> que{};
if(root) que.push(root);
while(!que.empty()) {
int n = que.size();
ans.emplace_back(vector<int>());
while(n--) {
auto p = que.front();
que.pop();
ans.back().emplace_back(p->val);
if(p->left) que.push(p->left);
if(p->right) que.push(p->right);
}
}
return ans;
}