学习笔记4——二叉树(C++版)

关于二叉树的算法题一般都是使用递归来实现,所以要想做好二叉树的算法题,要先学会递归算法的使用。

一、如何创建一个二叉树
1.声明一个树节点结构体
struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
2.创建节点
TreeNode *node1 = TreeNode(1);
TreeNode *node2 = TreeNode(2);
TreeNode *node3 = TreeNode(3);
TreeNode *node4 = TreeNode(4);
TreeNode *node5 = TreeNode(5);
TreeNode *node6 = TreeNode(6);
TreeNode *node7 = TreeNode(7);
3.连接节点
node1->left = node2;
node1->right = node3;
node2->left = node4;
node2->right = node5;
node3->left = node6;
node3->right = node7;
//和链表一样,知道第一个节点,就可以搜索所有的节点,所以我们可以用根部节点来代表整个二叉树
//即TreeNode* node1代表了整棵二叉树

这样一来,我们就创建了一个简单的二叉树了。

二、二叉树的分类

1.满二叉树 

除了最后一层,其他层都包含左右节点。

2.完全二叉树

树的1~n层是一个满二叉树,最后一层的节点全部靠左。(node5不能缺)

3.二叉搜索树

左树内所有的节点小于根节点,右数内所有的节点大于根节点。

注意:node5>node2,但是node5<node1。

4.平衡二叉树

平衡指的是左右平衡,左树右树高度差不超过1;左树右数都是一棵平衡树。

下面这棵树左边高度为2,右边为0,不是一棵平衡二叉树。

三、二叉树的遍历

我们拿这棵树来举例子。

1.深度优先遍历(DFS)

前序遍历(中左右)

void preOrder(TreeNode* root) {
    if (root == nullptr) {
        return;
    }
    std::cout << root->val << " ";  // 访问根节点
    preOrder(root->left);           // 遍历左子树
    preOrder(root->right);          // 遍历右子树
}
//输出node1、node2、node4、node5、node3、node6、node7

中序遍历(左中右)

void inOrder(TreeNode* root) {
    if (root == nullptr) {
        return;
    }
    inOrder(root->left);            // 遍历左子树
    std::cout << root->val << " ";  // 访问根节点
    inOrder(root->right);           // 遍历右子树
}
//输出node4、node2、node5、node1、node6、node3、node7

后续遍历(左右中)

void postOrder(TreeNode* root) {
    if (root == nullptr) {
        return;
    }
    postOrder(root->left);          // 遍历左子树
    postOrder(root->right);         // 遍历右子树
    std::cout << root->val << " ";  // 访问根节点
}
//输出node4、node5、node2、node6、node7、node3、node1
2.广度优先遍历(BFS)

层序遍历

void levelOrder(TreeNode* root) {
    if (root == nullptr) {
        return;
    }
    std::queue<TreeNode*> q;
    q.push(root);
    while (!q.empty()) {
        TreeNode* node = q.front();
        q.pop();
        std::cout << node->val << " ";
        if (node->left) q.push(node->left);
        if (node->right) q.push(node->right);
    }
}
//输出node1、node2、node3、node4、node5、node6、node7
//这段代码的意思是:第一轮,取树头、把左树压入队列、把右树压入队列
                  //第二轮,取左树的树头、把左树的左树压入队列、把左树的右树压入队列;
                   //然后取右树的树头、把右树的左树压入队列、把右树的右树压入队列;
                  //第三轮。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值