• 【C++课程学习】:二叉树的基本函数实现


    🎁个人主页:我们的五年

    🔍系列专栏:C++课程学习

    🎉欢迎大家点赞👍评论📝收藏⭐文章

     

    目录

    🍉二叉树的结构类型:

    🍉1.创建二叉树函数(根据数组,前序遍历创建二叉树):

    🍉2.销毁二叉树函数:

    🍉3.前序遍历函数:

    🍉4.二叉树的节点个数函数:

    🍉5.计算二叉树叶子节点的个数函数:

     🍉6.计算第k层的节点个数:

    🍉7.查找节点为k的元素,返回这个元素的指针

    🍉8.层序遍历,借助队列:

    🍉判断是否为完全二叉树:


    前言:

    学了那么久的二叉树,现在基本的二叉树学的差不多了,现在就给大家带来二叉树的几个基本函数。函数有几个,但是基本都不难,基本就是用了分治,递归的思想,画递归展开图也是一种很好理解递归过程好方法,等熟悉以后,就对递归有了更深的理解,面对有一些问题就直接可以写出来。

    🍉二叉树的结构类型:

    //二叉树的节点结构类型
    typedef struct BinaryTreeNode {
        BTDataType data;
        struct BinaryTreeNode* left;        //左孩子节点的地址
        struct BinaryTreeNode* right;        //右孩子的地址
    }BTNode;

    每个父节点都包:

    1.含存储的数据。

    2.左孩子地址。

    3.右孩子节点的地址。

    🍉1.创建二叉树函数(根据数组,前序遍历创建二叉树):

    画递归展开图也是很好理解的,先创建父亲节点,然后往左走,遇到‘#’,就返回NULL,返回上一层。

    1. //根据数组创建二叉树,下面举例的是字符数组,创建的顺序是前序遍历
    2. BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
    3. {
    4. if (a[*pi] == '#')
    5. {
    6. (*pi)++;
    7. return NULL;
    8. }
    9. BTNode* root = (BTNode*)malloc(sizeof(BTNode));
    10. root->data = a[*pi]; //前序遍历,先创建中间根节点
    11. (*pi)++;
    12. root->left = BinaryTreeCreate(a,pi); //左子树
    13. root->right = BinaryTreeCreate(a,pi); //右子树
    14. return root; //返回root节点
    15. }

    🍉2.销毁二叉树函数:

    销毁二叉树也可以前序遍历删除,也可以中序删除。不过如果是前序删除,就要在先保存左右孩子的节点。如果是中序删除,就是要保存右节点。

    只有后序遍历删除不要保存节点。

    1. // 二叉树销毁
    2. void BTDestory(BTNode** root)
    3. {
    4. if (*root == NULL)
    5. return;
    6. //后序遍历销毁二叉树
    7. BTDestory(&(*root)->left);
    8. BTDestory(&(*root)->right);
    9. free(*root);
    10. *root = NULL;
    11. }

    🍉3.前序遍历函数:

    前序遍历和中序遍历和后序遍历基本差不多,只有后面的两个函数和打印的顺序不一样。

    1. //前序遍历
    2. void BTPreOreder(BTNode* root)
    3. {
    4. if (root == NULL)
    5. {
    6. printf("# ");
    7. return;
    8. }
    9. printf("%c ",root->data);
    10. BTPreOreder(root->left);
    11. BTPreOreder(root->right);
    12. }

    🍉4.二叉树的节点个数函数:

    分治思想也是yyds

    1. // 二叉树节点个数
    2. int BTSize(BTNode* root)
    3. {
    4. if (root == NULL)
    5. return 0;
    6. //个数等于左树节点个数+右树节点个数+1
    7. return BTSize(root->left)+BTSize(root->right)+1;
    8. }

    🍉5.计算二叉树叶子节点的个数函数:

    分治

    1. // 二叉树叶子节点个数
    2. int BinaryTreeLeafSize(BTNode* root)
    3. { if (root == NULL)
    4. return 0;
    5. if (root->left == NULL && root->right == NULL)
    6. return 1;
    7. return BinaryTreeLeafSize(root->left) + BinaryTreeLeafSize(root->right);
    8. }

     🍉6.计算第k层的节点个数:

    要注意的是,遇到NULL,要返回,还有就是,k==1,return 1,要在后面,因为如果在前面,k确实等于1。但是这时候是空节点,所以不能return 1,所以return 1要在后面。

    1. // 二叉树第k层节点个数
    2. int BinaryTreeLevelKSize(BTNode* root, int k)
    3. {
    4. if (root == NULL)
    5. return 0;
    6. if (k == 1)
    7. {
    8. return 1;
    9. }
    10. return BinaryTreeLevelKSize(root->left, k - 1)+ BinaryTreeLevelKSize(root->right,k-1);
    11. }

    🍉7.查找节点为k的元素,返回这个元素的指针

    找父节点,父节点不是,就去左树,左树没有,就去右树。

    只要找到了就返回,所以是或的关系;

    1. // 二叉树查找值为x的节点
    2. BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
    3. {
    4. if (root == NULL)
    5. return NULL;
    6. if (root->data == x)
    7. return root;
    8. BTNode* p1 = BinaryTreeFind(root->left, x);
    9. if (p1!=NULL)
    10. return p1;
    11. BTNode* p2 = BinaryTreeFind(root->right, x);
    12. if (p2!=NULL)
    13. return p2;
    14. return NULL;
    15. }

    🍉8.层序遍历,借助队列:

    先在队列中插入root,在队列头出一个数据,就入这个节点的左右孩子节点。因为队列有先进先出的特点,所以能达到层序的目的。

    1. // 层序遍历
    2. void BinaryTreeLevelOrder(BTNode* root)
    3. {
    4. Queue ps;
    5. QueueInit(&ps);
    6. QueuePush(&ps, root);
    7. while (!QueueEmpty(&ps))
    8. {
    9. BTNode* node = QueueTop(&ps);
    10. if (node == NULL)
    11. {
    12. break;
    13. }
    14. else
    15. {
    16. printf("%c ", node->data);
    17. QueuePush(&ps, node->left);
    18. QueuePush(&ps, node->right);
    19. }
    20. QueuePop(&ps);
    21. }
    22. QueueDestroy(&ps);
    23. }

    🍉9.判断是否为完全二叉树:

    先入数据,然后出,和层序遍历一样,当需要NULL就结束。然后看后面的队列是否都是NULL,如果只要有一个不是NULL,那肯定就不是完全二叉树了,前面都有NULL,后面又出现节点。

    1. // 判断二叉树是否是完全二叉树
    2. int BinaryTreeComplete(BTNode* root)
    3. {
    4. Queue ps;
    5. QueueInit(&ps);
    6. QueuePush(&ps, root);
    7. while (!QueueEmpty(&ps))
    8. {
    9. BTNode* node = QueueTop(&ps);
    10. if (node == NULL)
    11. {
    12. break;
    13. }
    14. else
    15. {
    16. QueuePush(&ps, node->left);
    17. QueuePush(&ps, node->right);
    18. }
    19. QueuePop(&ps);
    20. }
    21. while (!QueueEmpty(&ps))
    22. {
    23. BTNode* node = QueueTop(&ps);
    24. if (node != NULL)
    25. return 0;
    26. QueuePop(&ps);
    27. }
    28. return 1;
    29. }

  • 相关阅读:
    使用Python+moviepy保存截取视频画面
    linux之top、ps、free命令详解
    基于php+MySQL电脑外设商城网站毕业设计源码271538
    互联网安全面临的全新挑战
    mysql语句
    外贸建站教程步骤有哪些?独立站怎么搭建?
    WebRTC系列 -- iOS 音频采集
    整车热管理「升温」,哪些厂商排名电子风扇市场份额TOP10
    推荐收藏,机器学习7种特征编码太好用了
    (四)进程管理:进程基本概念
  • 原文地址:https://blog.csdn.net/djdjiejsn/article/details/139277847