代码随想录第14天|二叉树

二叉树

理论基础

种类

  • 满二叉树

    • 除了最后一层, 其余节点都是满的
    • 在这里插入图片描述
  • 完全二叉树

    • 除了最后一层没满, 并且是从左到右
    • 大根堆或小根堆
    • 在这里插入图片描述
  • 二叉搜索树

    • 时间复杂度O(logn)
    • 元素有一定顺序, 结构没要求
    • 在这里插入图片描述
  • 平衡二叉搜索树

    • 左子树和右子树的高度差不能超过1
    • map、set、multimap和multiset底层是由平衡二叉搜索树实现的, 所以一定是有序的
    • 在这里插入图片描述

存储方式

  • 链式存储

    • 在这里插入图片描述
  • 顺序存储

    • 在这里插入图片描述

遍历方式

  • 深度优先遍历

    • 前序遍历(递归法,迭代法)
    • 中序遍历(递归法,迭代法)
    • 后序遍历(递归法,迭代法)
    • 在这里插入图片描述
  • 广度优先遍历

    • 层次遍历(迭代法)

定义

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

/* 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. 单层递归逻辑

例题:
144.二叉树的前序遍历
145.二叉树的后序遍历
94.二叉树的中序遍历

实现

class Solution {
public:
	//前序遍历
    void preorder(TreeNode* root, vector<int>& result) {
        if (root == nullptr) return;
        result.push_back(root->val);
        preorder(root->left, result);
        preorder(root->right, result);
    }
    //中序遍历
    void inorder(){
		if (root == nullptr) return;        
        preorder(root->left, result);
        result.push_back(root->val);
        preorder(root->right, result);
	}
    //后序遍历
    void postorder(TreeNode* root, vector<int>& result) {
    	if (root == nullptr) return;
        preorder(root->left, result);
        preorder(root->right, result);
        result.push_back(root->val);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        preorder(root, result);
        return result;
    }
};

迭代遍历

实现

//前序遍历时, 使用栈实现
//入栈顺序: 根 -> 右, 左 (出栈为: 根) -> 右 (出栈为: 左)-> (出栈为: 右)
//出栈结果:		根 -> 左 -> 右
vector<int> preorderTraversal(TreeNode* root) {
    	stack<TreeNode*> mystack;
    	vector<int> result;
    	if (root) mystack.push(root);
    	while (!mystack.empty()) {
        	TreeNode* tem = mystack.top();
        	mystack.pop();
        	if (tem-> right) mystack.push(tem->right);
        	if (tem-> left) mystack.push(tem->left);
        	result.push_back(tem->val);
    	}
    	return result;
}

//后序遍历为: 根 左 右
//根 左 右 -> 根 右 左 -> 左 右 根
//调换两次顺序即可实现
vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> mystack;
        vector<int> result;
        if (root) mystack.push(root);
        while (!mystack.empty()) {
            TreeNode* tem = mystack.top();
            mystack.pop();
            if (tem-> left) mystack.push(tem->left);
            if (tem-> right) mystack.push(tem->right);
            result.push_back(tem->val);
        }
        reverse(result.begin(), result.end());
        return result;
    }

//中序遍历
vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        stack<TreeNode*>mystack;
        TreeNode* cur = root;
        while (cur != nullptr || !mystack.empty()) {
            if (cur != nullptr) {
                mystack.push(cur);
                cur = cur->left;
            } else {
                cur = mystack.top();
                mystack.pop();
                result.push_back(cur->val);
                cur = cur->right;
            }
        }
        return result;
    }

统一迭代

实现

  • 依靠NULL点区分是否将下一个元素加入结果中
//前序遍历
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;
}

//中序遍历
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;
}

//后序遍历
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;
}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值