• 数据结构初阶 —— 二叉树链式结构


    目录

     一,二叉树链式结构

    二,二叉树的遍历(四种)

    前序遍历

    中序遍历

    后序遍历

    层序遍历

    三,二叉树接口

    四,试题


     一,二叉树链式结构

    • 普通二叉树的增删查改,意义不大;
    • 普通二叉树+搜索树规则,增删查改才有价值;
    1. //二叉树链式结构
    2. typedef int BTDataType;
    3. typedef struct BinaryTreeNode
    4. {
    5. BTDataType _data;
    6. struct BinaryTreeNode* _left;
    7. struct BinaryTreeNode* _right;
    8. }BTNode;
    9. //创建节点
    10. BTNode* BuyNode(BTDataType x)
    11. {
    12. BTNode* node = (BTNode*)malloc(sizeof(BTNode));
    13. if (node == NULL)
    14. {
    15. perror("BuyNode");
    16. exit(-1);
    17. }
    18. node->_data = x;
    19. node->_left = node->_right = NULL;
    20. return node;
    21. }
    22. //自定义二叉树
    23. BTNode* CreatBinaryTree()
    24. {
    25. BTNode* nodeA = BuyNode('A');
    26. BTNode* nodeB = BuyNode('B');
    27. BTNode* nodeC = BuyNode('C');
    28. BTNode* nodeD = BuyNode('D');
    29. BTNode* nodeE = BuyNode('E');
    30. BTNode* nodeF = BuyNode('F');
    31. nodeA->_left = nodeB;
    32. nodeA->_right = nodeC;
    33. nodeB->_left = nodeD;
    34. nodeC->_left = nodeE;
    35. nodeC->_right = nodeF;
    36. return nodeA;
    37. }

    二,二叉树的遍历(四种)

    • 前序遍历,根 \rightarrow 左子树 \rightarrow 右子树;
    • 中序遍历,左子树 \rightarrow 根 \rightarrow 右子树;
    • 后序遍历,左子树 \rightarrow 右子树 \rightarrow 根;
    • 层序遍历,一层一层遍历;

    注:深度优先遍历(前序、中序、后序),广度优先遍历(层序);

    前序遍历

    1. //前序遍历
    2. void PreOrder(BTNode* root)
    3. {
    4. if (root == NULL)
    5. return;
    6. printf("%c ", root->_data);
    7. PreOrder(root->_left);
    8. PreOrder(root->_right);
    9. }

    中序遍历

    1. //中序遍历
    2. void InOrder(BTNode* root)
    3. {
    4. if (root == NULL)
    5. return;
    6. InOrder(root->_left);
    7. printf("%c ", root->_data);
    8. InOrder(root->_right);
    9. }

    后序遍历

    1. //后序遍历
    2. void PostOrder(BTNode* root)
    3. {
    4. if (root == NULL)
    5. return;
    6. PostOrder(root->_left);
    7. PostOrder(root->_right);
    8. printf("%c ", root->_data);
    9. }

    层序遍历

    1. //层序遍历-利用队列
    2. //一个节点出列,就将其子左右节点入列
    3. typedef struct BinaryTreeNode* QDataType;
    4. //队列中节点
    5. typedef struct QueueNode
    6. {
    7. QDataType data;
    8. struct QueueNode* next;
    9. }QueueNode;
    10. //队列
    11. typedef struct Queue
    12. {
    13. QueueNode* phead;
    14. QueueNode* ptail;
    15. }Queue;
    16. void LevelOrder(BTNode* root)
    17. {
    18. Queue q;
    19. QueueInit(&q);
    20. if(root)
    21. QueuePush(&q, root);
    22. while(!QueueEmpty(&q))
    23. {
    24. BTNode* front = QueueFront(&q);
    25. QueuePop(&q);
    26. printf("%c ", front->val);
    27. if(front->left)
    28. QueuePush(&q, front->left);
    29. if(front->right)
    30. QueuePush(&q, front->right);
    31. }
    32. printf("\n");
    33. QueueDestroy(&q);
    34. }

    三,二叉树接口

    1. //求二叉树节点个数-递归
    2. //方法一,全局变量或static
    3. int size = 0;
    4. void BinaryTreeSize(BTNode* root)
    5. {
    6. if (root)
    7. size++;
    8. else
    9. return;
    10. BinaryTreeSize(root->_left);
    11. BinaryTreeSize(root->_right);
    12. }
    13. //方法二,局部变量-传址
    14. void BinaryTreeSize(BTNode* root, int* psize)
    15. {
    16. if (root)
    17. (*psize)++;
    18. else
    19. return;
    20. BinaryTreeSize(root->_left, psize);
    21. BinaryTreeSize(root->_right, psize);
    22. }
    23. //方法三,返回值
    24. int BinaryTreeSize(BTNode* root)
    25. {
    26. if (root)
    27. return 1 + BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right);
    28. else
    29. return 0;
    30. }
    1. //求二叉树叶子节点个数
    2. int BinaryTreeLeafSize(BTNode* root)
    3. {
    4. if (root == NULL)
    5. return 0;
    6. if (root->_left == NULL && root->_right == NULL)
    7. return 1;
    8. return BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
    9. }
    1. //求二叉树第k层节点个数
    2. //当前树第K层节点个数 = 其左子树的第K-1层节点个数 + 其右子树的第K-1层节点个数
    3. int BinaryTreeLevelKSize(BTNode* root, int k)
    4. {
    5. if (root == NULL)
    6. return 0;
    7. if (k == 1)
    8. return 1;
    9. return BinaryTreeLevelKSize(root->_left, k - 1) + BinaryTreeLevelKSize(root->_right, k - 1);
    10. }
    1. //求二叉树深度
    2. //当前树深度 = max(左子树深度, 右子树深度) + 1;
    3. int BinaryTreeDepth(BTNode* root)
    4. {
    5. if (root == NULL)
    6. return 0;
    7. int leftDepth = BinaryTreeDepth(root->_left);
    8. int rightDepth = BinaryTreeDepth(root->_right);
    9. return leftDepth > rightDepth ? (1 + leftDepth) : (1 + rightDepth);
    10. }
    1. //二叉树查找值为x的节点
    2. //先当前节点查找,没有,在去左子树查找,没有,在取右子树查找
    3. BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
    4. {
    5. if (root == NULL)
    6. return NULL;
    7. if (root->_data == x)
    8. return root;
    9. BTNode* retLeft = BinaryTreeFind(root->_left, x);
    10. if (retLeft)
    11. return retLeft;
    12. BTNode* retRight = BinaryTreeFind(root->_right, x);
    13. if (retRight)
    14. return retRight;
    15. return NULL;
    16. }
    1. //二叉树的销毁
    2. void BinaryTreeDestory(BTNode* root)
    3. {
    4. if(root==NULL)
    5. return;
    6. BinaryTreeDestory(root->left);
    7. BinaryTreeDestory(root->right);
    8. free(root);
    9. }
    1. //判断二叉树是否是完全二叉树
    2. //利用层序,空也入列,完全二叉树非空是连续的
    3. bool BinaryTreeComplete(BTNode* root)
    4. {
    5. Queue q;
    6. QueueInit(&q);
    7. if(root)
    8. QueuePush(&q, root);
    9. while(!QueueEmpty(&q))
    10. {
    11. BTNode* front = QueueFront(&q);
    12. QueuePop(&q);
    13. if(front == NULL)
    14. break;
    15. QueuePush(&q, front->left);
    16. QueuePush(&q, front->right);
    17. }
    18. while(!QueueEmpty(&q))
    19. {
    20. BTNode* front = QueueFront(&q);
    21. QueuePop(&q);
    22. if(front)
    23. {
    24. QueueDestroy(&q);
    25. return false;
    26. }
    27. }
    28. QueueDestroy(&q);
    29. return true;
    30. }

    四,试题

    (前序/后序:可得到根,中序:可得到左右树的区间)

    • 前序+中序,可重建树;
    • 后序+中序,可重建树;
    • 前序+后序,不可重建树;

  • 相关阅读:
    持续集成交付CICD:Jenkins通过API触发流水线
    Java——String类全面解析
    第53篇-某天猫评论sign参数分析【2022-08-31】
    Axure学习记录(菜单下拉/收起效果)
    C# 数据分页
    pycharm 中package, directory, sources root, resources root的区别
    腾讯云产品可观测最佳实践 (Function)¶
    shopee选品软件:解决你店铺选品难题的神器-shopee选品软件知虾
    sql注入(其他)
    protobuf 详解
  • 原文地址:https://blog.csdn.net/NapoleonCoder/article/details/130857021