二叉树之理解记忆并背诵,了解一下?

版权声明:文章为作者原创,转载请注明出处 https://blog.csdn.net/u010352603/article/details/79874055

内容主要包含:
1. 二叉树中DFS三种搜索的模板程序 (递归+非递归)
2. 二叉树BFS非递归版本
3. 二叉树常见到必背的考题
不管你是刷题学习,还是准备面试,二叉树下面的这几个程序都是 理解记忆并背诵!理解记忆并背诵!理解记忆并背诵!重要的事情说三遍

真的太常用了,小哥哥小姐姐一定要掌握哦~

BFS递归版本

void bfs(TreeNode *node, queue<TreeNode*> q) {
    if (q.empty()) {
        return;
    }

    TreeNode *node = q.front();
    q.pop();
    cout << node->val << endl;

    if (node->left) {
        q.push(node->left);
    }
    if (node->right) {
        q.push(node->right);
    }

    bfs(node, q);
}

二叉树中序遍历

非递归1-最通用的版本

    vector<int> inorderTraversal(TreeNode * root) {
        if (root == NULL) {
            return vector<int>();
        }

        vector<int> ret;
        stack<TreeNode*> s;

        while (root != NULL) {
            s.push(root);
            root = root->left;
        }

        while (!s.empty()) {
            TreeNode *curt = s.top();
            ret.push_back(curt->val);

            if (curt->right == NULL) {
                s.pop();
                while (!s.empty() && s.top()->right == curt) {
                    curt = s.top();
                    s.pop();
                }
            } else {
                curt = curt->right;
                while (curt != NULL) {
                    s.push(curt);
                    curt = curt->left;
                }
            }
        }

        return ret;
    }

非递归2-常见版本

vector<int> inorderTraversal(TreeNode * root) {
        // 中序遍历的非递归版本
        vector<int> result;
        stack<TreeNode*> s;
        TreeNode* cur = root;

        while(cur != NULL || !s.empty()) {
            while(cur != NULL) {
                s.push(cur);
                cur = cur->left;
            }
            cur = s.top();
            s.pop();
            result.push_back(cur->val);
            cur = cur->right;
        }
        return result;
    }

二叉树前序遍历

递归之traverse

    vector<int> preorderTraversal(TreeNode * root) {
        vector<int> result;
        // 定义:以root为根节点的先序遍历结果放到result中
        traverse(root, result); 
        return result;
    }

    void traverse(TreeNode *root, vector<int> &result) { // 这个地方每次都要传地址,因为每次都要修改,相当于一个全局变量
        if (root == NULL) {
            return;
        }

        result.push_back(root->val);
        traverse(root->left, result);
        traverse(root->right, result);
    }

非递归版本

vector<int> preorderTraversal(TreeNode * root) {
    if (root == NULL) {
        return vector<int>();
    }

    vector<int> result;
    stack<TreeNode*> s;


    s.push(root);
    while(!s.empty()) {
        TreeNode *node = s.top();
        s.pop();
        result.push_back(node->val);
        if(node->right!=NULL) {
            s.push(node->right);
        }
        if(node->left!=NULL) {
            s.push(node->left);
        }
    }

    return result;
}

二叉树后序遍历

非递归版本

vector<int> postorderTraversal(TreeNode * root) {
    // write your code here
    vector<int> result;
    stack<TreeNode*> s;

    TreeNode *current = root, *lastVisit = NULL;
    while(current!=NULL || !s.empty()) {
        while(current != NULL) {
            s.push(current);
            current = current->left;
        }
        current = s.top(); // 此时先不要急着出栈
        if(current->right == NULL || current->right == lastVisit) {
            s.pop();
            result.push_back(current->val);
            lastVisit = current;
            current = NULL;
        } else {
            current = current->right;
        }
    }
    return result;
}

二叉树基本考题

MaxDepth of binary tree

int maxDepth(TreeNode *root) {
    // write your code here
    if(root == NULL) {
        return 0;
    }

    // Divide
    int left = maxDepth(root->left);
    int right = maxDepth(root->right);

    // Conquer
    return max(left, right) + 1;
}

MinDepth of binary tree

int minDepth(TreeNode * root) {
        // write your code here
        if(root == NULL) {
            return 0;
        }

        // Divide
        int left = minDepth(root->left);
        int right = minDepth(root->right);

        // Conquer
        if(left == 0 && right == 0) {
            return 1;
        }else if(left == 0 && right != 0) {
            return right + 1;
        }else if(left != 0 && right == 0) {
            return left + 1;
        }else {
            return min(left, right) + 1;
        }
    }

平衡二叉树判断

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */


class ResultType {
public:
    int maxDepth;
    bool isBalanced;

public:
    ResultType(int maxDepth, int isBalanced) {
        this->maxDepth = maxDepth;
        this->isBalanced = isBalanced;
    }
};


class Solution {
public:
    /*
     * @param root: The root of binary tree.
     * @return: True if this Binary tree is Balanced, or false.
     */
    bool isBalanced(TreeNode * root) {
        // write your code here
        return helper(root).isBalanced;
    }

    ResultType helper(TreeNode* root) {
        if(root == NULL) {
            return ResultType(0, true);
        }

        // Divide
        ResultType left = helper(root->left);
        ResultType right = helper(root->right);

        // Conquer
        if(!left.isBalanced || !right.isBalanced) {
            return ResultType(-1, false);
        }
        if(abs(left.maxDepth - right.maxDepth) > 1) {
            return ResultType(-1, false);
        }
        return ResultType(max(left.maxDepth, right.maxDepth) + 1, true);
    }
};

二叉搜索树判断

class Solution {
public:

    bool isValid;
    TreeNode *lastNode;

    bool isValidBST(TreeNode * root) {
        lastNode = NULL;
        isValid = true;

        traverse(root);

        return isValid;
    }

    // 利用中序遍历是升序序列的特性来做,一边遍历一遍给出结果
    void traverse(TreeNode *root) {
        // 先处理特殊情况,或者是退出情况
        if (root == NULL) {
            return;
        }

        traverse(root->left);
        // 根
        if (lastNode != NULL && lastNode->val >= root->val) {
            isValid = false;
            return;
        }
        lastNode = root;

        traverse(root->right);
    }
};
// 不要去记录最大值最小值,当节点为NULL的时候,不好处理。记录下最小最大的节点。不存在的话就直接给NULL就行了。
struct ResultType {
    bool isBST;
    TreeNode *maxNode;
    TreeNode *minNode;
    ResultType(bool isBST) {
        this->isBST = isBST;
        this->maxNode = NULL;
        this->minNode = NULL;
    }
};

    bool isValidBST(TreeNode * root) {
        return helper(root)->isBST;
    }

    ResultType *helper(TreeNode *root) {
        if (root == NULL) {
            return new ResultType(true);
        }

        // Divide
        ResultType *left = helper(root->left);
        ResultType *right = helper(root->right);

        // Conquer
        // 先处理不是的情况
        if (!left->isBST || !right->isBST) {
            return new ResultType(false);
        }

        if (left->maxNode != NULL && left->maxNode->val >= root->val) {
            return new ResultType(false);
        }

        if (right->minNode != NULL && right->minNode->val <= root->val ) {
            return new ResultType(false);
        }

        // 最后处理复杂的是的情况
        ResultType *ret = new ResultType(true); // 首先,是BST
        ret->minNode = left->minNode != NULL ? left->minNode : root;
        ret->maxNode = right->maxNode != NULL ? right->maxNode : root;
        return ret;

    }

二叉树中最近公共祖先 (Lowest Common Anscestor)

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */


class Solution {
public:
    /*
     * @param root: The root of binary tree
     * @return: An integer
     */
    int minDepth(TreeNode * root) {
        // write your code here
        if(root == NULL) {
            return 0;
        }

        // Divide
        int left = minDepth(root->left);
        int right = minDepth(root->right);

        // Conquer
        if(left == 0 && right == 0) {
            return 1;
        }else if(left == 0 && right != 0) {
            return right + 1;
        }else if(left != 0 && right == 0) {
            return left + 1;
        }else {
            return min(left, right) + 1;
        }
    }
};

二叉树路径和最大值

public int maxPathSum(TreeNode *root) {
  if(root == NULL) {
    return 0;
  }

  // Divide
  int left = maxPathSum(root->left);
  int right = maxPathSum(root->right);

  // Conquer
  //root->leaf
  return max(left, right) + root->val;

  // root->any
  return max(max(left, right), 0) + root->val; // 也就是说如果是到any节点,那么如果是负数,我们不如不要他,但是如果是到leaf则不行,不管是不是负的,你都必须走到leaf才行。
}
// any->any 用到两个分治法


class ResultType {
public:
    int any2any;
    int root2any;
    ResultType(int root2any, int any2any) {
        this->root2any = root2any;
        this->any2any = any2any;
    }
};


class Solution {
public:
    /*
     * @param root: The root of binary tree.
     * @return: An integer
     */
    int maxPathSum(TreeNode * root) {
        // write your code here
        return helper(root).any2any;
    }

    ResultType helper(TreeNode *root) {
        //illegal 这种情况是不合法,找不到 不是找到为0
        if(root == NULL) {
            return ResultType(INT_MIN, INT_MIN);
        }

        // Divide
        ResultType left = helper(root->left);
        ResultType right = helper(root->right);

        // Conquer
        int any2any =  max(left.any2any, right.any2any);
        int root2any = max(0, max(left.root2any, right.root2any)) + root->val;
        any2any = max(any2any, 
                    max(left.root2any, 0) + max(right.root2any, 0) + root->val);
        return ResultType(root2any, any2any);
    }
};
展开阅读全文

没有更多推荐了,返回首页