力扣刷题笔记:二叉树遍历(9)

144. 二叉树的前序遍历(深搜、栈)

递归:

class Solution {
     
public:
    vector<int> ans;
    vector<int> preorderTraversal(TreeNode* root) {
     
        dfs(root);
        return ans;
    }
    void dfs(TreeNode* root){
     
        if(root==NULL)	return;
        ans.push_back(root->val);
        dfs(root->left);
        dfs(root->right);
    }
};

非递归法:

class Solution {
     
public:
    vector<int> preorderTraversal(TreeNode* root) {
     
        stack<TreeNode*> st;
        vector<int> result;
        if (root == NULL) return result;
        st.push(root);
        while (!st.empty()) {
     
            TreeNode* node = st.top();                       // 中
            st.pop();
            result.push_back(node->val);
            if (node->right) st.push(node->right);           // 右(空节点不入栈)
            if (node->left) st.push(node->left);             // 左(空节点不入栈)
        }
        return result;
    }
};

统一模板:

class Solution {
     
public:
    vector<int> preorderTraversal(TreeNode* root) {
     
        vector<int> result;
        stack<TreeNode*> st;
        if (root != NULL) st.push(root);
        while (!st.empty()) {
     
            TreeNode* node = st.top();
            if (node != NULL) {
     
                st.pop();
                if (node->right) st.push(node->right);  // 右
                if (node->left) st.push(node->left);    // 左
                st.push(node);                          // 中
                st.push(NULL);
            } else {
     
                st.pop();
                node = st.top();
                st.pop();
                result.push_back(node->val);
            }
        }
        return result;
    }
};

94. 二叉树的中序遍历(深搜、栈)

1、中序遍历包含递归和非递归两种做法
2、递归方法包含一个隐式栈,所以也可以用栈的方法实现遍历。
3、非递归方法每次沿左节点遍历,找到无左孩子的节点,输出再找右节点,以此类推。

递归:

class Solution {
     
public:
    vector<int> ans;
    vector<int> inorderTraversal(TreeNode* root) {
     
        dfs(root);
        return ans;
    }
    void dfs(TreeNode* root){
     
        if(root==NULL)	return;
        dfs(root->left);
        ans.push_back(root->val);
        dfs(root->right);
    }
};

非递归:

class Solution {
     
public:
    vector<int> inorderTraversal(TreeNode* root) {
     
        vector<int> res;
        stack<TreeNode*> stk;
        while (root != nullptr || !stk.empty()) {
     
            while (root != nullptr) {
     
                stk.push(root);
                root = root->left;
            }
            root = stk.top();
            stk.pop();
            res.push_back(root->val);
            root = root->right;
        }
        return res;
    }
};

统一模板:

class Solution {
     
public:
    vector<int> inorderTraversal(TreeNode* root) {
     
        vector<int> result;
        stack<TreeNode*> st;
        if (root != NULL) st.push(root);
        while (!st.empty()) {
     
            TreeNode* node = st.top();
            if (node != NULL) {
     
                st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
                if (node->right) st.push(node->right);  // 添加右节点(空节点不入栈)
                st.push(node);                          // 添加中节点
                st.push(NULL); // 中节点访问过,但是还没有处理,加入空节点做为标记。
                if (node->left) st.push(node->left);    // 添加左节点(空节点不入栈)
            } else {
      // 只有遇到空节点的时候,才将下一个节点放进结果集
                st.pop();           // 将空节点弹出
                node = st.top();    // 重新取出栈中元素
                st.pop();
                result.push_back(node->val); // 加入到结果集
            }
        }
        return result;
    }
};

145. 二叉树的后序遍历(深搜、栈)

递归:

class Solution {
     
public:
    vector<int> ans;
    vector<int> postorderTraversal(TreeNode* root) {
     
        dfs(root);
        return ans;
    }
    void dfs(TreeNode* root){
     
        if(root==NULL)	return;
        dfs(root->left);
        dfs(root->right);
        ans.push_back(root->val);
    }
};

非递归:

class Solution {
     
public:
    vector<int> postorderTraversal(TreeNode* root) {
     
        stack<TreeNode*> st;
        vector<int> result;
        if (root == NULL) return result;
        st.push(root);
        while (!st.empty()) {
     
            TreeNode* node = st.top();
            st.pop();
            result.push_back(node->val);
            if (node->left) st.push(node->left);
            // 相对于前序遍历,这更改一下入栈顺序 (空节点不入栈)
            if (node->right) st.push(node->right); // 空节点不入栈
        }
        reverse(result.begin(), result.end()); // 将结果反转之后就是左右中的顺序了
        return result;
    }
};

统一模板:

class Solution {
     
public:
    vector<int> postorderTraversal(TreeNode* root) {
     
        vector<int> result;
        stack<TreeNode*> st;
        if (root != NULL) st.push(root);
        while (!st.empty()) {
     
            TreeNode* node = st.top();
            if (node != NULL) {
     
                st.pop();
                st.push(node);                          // 中
                st.push(NULL);

                if (node->right) st.push(node->right);  // 右
                if (node->left) st.push(node->left);    // 左

            } else {
     
                st.pop();
                node = st.top();
                st.pop();
                result.push_back(node->val);
            }
        }
        return result;
    }
};

102. 二叉树的层序遍历(广搜)

1、层序遍历算法使用广度优先搜索,算法使用队列实现。
2、输出格式是按行分的二维数组,所以记录每次输出时队列的长度。

class Solution {
     
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
     
    queue<TreeNode*> q;
    if (root==NULL) return {
     };
    q.push(root);
    vector<vector<int>> ans;
    while(!q.empty()){
     
        vector<int> set;
        //队列的长度是个变量,必须事先记录
        int num=q.size();
        for(int i=0;i<num;i++) {
     
            TreeNode* temp=q.front();
            q.pop();
            set.push_back(temp->val);
            if(temp->left!=NULL) q.push(temp->left);
            if(temp->right!=NULL) q.push(temp->right); 
        } 
        ans.push_back(set);
    }
    return ans;
    }
};

103. 二叉树的锯齿形层序遍历(广搜)

1、思路与二叉树层序遍历类似,使用广搜,树用链表,用双端队列存树节点,返回二维数组
2、根据行的奇偶决定从双端队列的头插还是尾插

vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
     
        vector<vector<int>> ans;
        if (!root) 
            return ans;
        queue<TreeNode*> nodeQueue;
        nodeQueue.push(root);
        bool isOrderLeft = true;
        while (!nodeQueue.empty()) {
     
            deque<int> levelList;
            int size = nodeQueue.size();
            for (int i = 0; i < size; ++i) {
     
                auto node = nodeQueue.front();
                nodeQueue.pop();
                if (isOrderLeft) 
                    levelList.push_back(node->val);
                else 
                    levelList.push_front(node->val);
                if (node->left) 
                    nodeQueue.push(node->left);
                if (node->right) 
                    nodeQueue.push(node->right);
            }
            ans.emplace_back(vector<int>{
     levelList.begin(), levelList.end()});
            isOrderLeft = !isOrderLeft;
        }
        return ans;
    }

98. 二叉搜索树(深搜)

递归函数传入最小值和最大值,递归遍历左右子树时,值不能超过最大最小值的范围

class Solution {
     
public:
    bool helper(TreeNode* root, long long lower, long long upper) {
     
        if (root == nullptr) 
            return true;
        if (root -> val <= lower || root -> val >= upper) 
            return false;
        return helper(root -> left, lower, root -> val) && helper(root -> right, root -> val, upper);
    }
    bool isValidBST(TreeNode* root) {
     
        return helper(root, LONG_MIN, LONG_MAX);
    }
};

110. 平衡二叉树(双深搜)

1、平衡二叉树左右子树的高度差不超过1
2、使用双递归函数的方法进行判断,一个递归函数负责递归判断每个节点是不是平衡二叉树
3、第二个递归函数负责判断每个节点的深度是多少

class Solution {
     
public:
    int height(TreeNode* root) {
     
        if (root == NULL) 
            return 0;
        else 
            return max(height(root->left), height(root->right)) + 1;
    }
    bool isBalanced(TreeNode* root) {
     
        if (root == NULL) 
            return true;
        else 
            return abs(height(root->left) - height(root->right)) <= 1 
            && isBalanced(root->left) && isBalanced(root->right);
    }
};

958. 完全二叉树(广搜)

用层序遍历广度优先搜索队列做,当出现空节点时,如果后面没有节点,则是完全二叉树,有节点则不是

   bool isCompleteTree(TreeNode* root) {
     
        queue<TreeNode*> q;
        q.push(root);
        int flag=0;
        while(!q.empty()){
     
            TreeNode* temp=q.front();
            q.pop();
            if(temp==nullptr)
                flag=1;
            else{
     
                if(flag==1)
                    return false;
                else {
     
                    q.push(temp->left);
                    q.push(temp->right);
                }
            }
        }
        return true;
    }

剑指 Offer 36. 二叉搜索树与双向链表(深搜)

题目要求的双向链表是二叉搜索树的中序遍历,先遍历一遍把节点存在节点数组中,在两轮遍历把前后指针接上

class Solution {
     
public:
    vector<Node*> list;
    Node* treeToDoublyList(Node* root) {
     
    	//先中序遍历,用vector存储两边,再处理双向循环
    	if(root==NULL) return NULL;
    		dfs(root);
   		int n=list.size();
    	list[0]->left=list[n-1];
    	list[n-1]->right=list[0];
    	//遍历完的结果,必须left和right都找一遍
    	for(int i=0;i<n-1;i++)
        	list[i]->right=list[i+1];
    	for(int i=1;i<n;i++)
        	list[i]->left=list[i-1];
   		return list[0];
    }
    void dfs(Node* root){
     
        if(root==NULL) 
        	return;
        dfs(root->left);
        list.push_back(root);
        dfs(root->right);
    }
};

你可能感兴趣的:(力扣刷题)