当前位置:   article > 正文

数据结构(特殊二叉树-线索二叉树)

数据结构(特殊二叉树-线索二叉树)
一、线索二叉树
  • 规律:在有n个节点的链式二叉树中必定存在 n+1 个空指针

  • 链式二叉树中有很多的空指针,可以让这些空指针指向前一个节点\后一个节点,从而在有序遍历(中序遍历)二叉树时,不需要使用递归而通过循环即可以完成,并且效率要比递归快得多

  • 一定是搜索二叉树

线索二叉树的结构
typedef struct TreeNode
{
    int data;   //  数据域
    struct TreeNode* left;
    bool lflag;     //  左子树是否是线索  为真时,左子树是线索 指向前一个节点
    struct TreeNode* right;
    bool rflag;     //  右子树是否是线索  为真时,右子树是线索 指向下一个节点
}TreeNode;
构建线索二叉树
  • 首先需要有一颗搜索二叉树,然后通过中序遍历并生成线索,通过检查右子树是否为空来决定是否生成线索,让右子树指向下一个节点。

  • 当构成线索二叉树后 ,可以通过循环遍历的方式有序遍历二叉树,不需要中序递归遍历也可以

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. typedef struct TreeNode
  5. {
  6. int data; // 数据域
  7. struct TreeNode* left;
  8. struct TreeNode* right;
  9. bool rflag; // 右子树是否是线索 为真时,右子树是线索 指向下一个节点
  10. }TreeNode;
  11. TreeNode* create_tree_node(int data)
  12. {
  13. TreeNode* node = malloc(sizeof(TreeNode));
  14. node->data = data;
  15. node->left = NULL;
  16. node->right = NULL;
  17. node->rflag = false; // 默认非线索
  18. return node;
  19. }
  20. void _insert_tree(TreeNode** root,TreeNode* node)
  21. {
  22. if(NULL == *root)
  23. {
  24. *root = node;
  25. return;
  26. }
  27. if(node->data < (*root)->data)
  28. _insert_tree(&((*root)->left),node);
  29. else
  30. _insert_tree(&((*root)->right),node);
  31. }
  32. // 添加还是按照搜索二叉树的规则
  33. void insert_tree(TreeNode** root,int val)
  34. {
  35. TreeNode* node = create_tree_node(val);
  36. _insert_tree(root,node);
  37. }
  38. void ldr_show(TreeNode* root)
  39. {
  40. if(NULL == root) return;
  41. ldr_show(root->left);
  42. printf("%d ",root->data);
  43. ldr_show(root->right);
  44. }
  45. // 按中序遍历时,当前root节点的前一个节点
  46. TreeNode* prev = NULL;
  47. // 按照中序进行遍历 并创建线索
  48. void create_clue(TreeNode* root)
  49. {
  50. if(NULL == root) return;
  51. // 给左子树创建线索
  52. create_clue(root->left);
  53. // 检查prev是否要创建线索
  54. // 当prev指向树节点 且prev的右子树为空 可以创建线索 指向下一个节点root
  55. if(NULL != prev && NULL == prev->right)
  56. {
  57. prev->right = root;
  58. prev->rflag = true;
  59. }
  60. prev = root;
  61. // 给右子树创建线索
  62. create_clue(root->right);
  63. }
  64. // 按照线索进行循环遍历 无需递归
  65. void clue_show(TreeNode* root)
  66. {
  67. while(root)
  68. {
  69. // 让root走到最小值节点位置
  70. while(root->left) root = root->left;
  71. printf("%d ",root->data);
  72. // root右子树是线索 指向下一个节点 直到root的右子树不是线索
  73. while(root->rflag)
  74. {
  75. root = root->right;
  76. printf("%d ",root->data);
  77. }
  78. root = root->right;
  79. }
  80. }
  81. int main(int argc,const char* argv[])
  82. {
  83. TreeNode* root = NULL;
  84. for(int i=0; i<10; i++)
  85. {
  86. int num = rand()%100;
  87. insert_tree(&root,num);
  88. printf("%d ",num);
  89. }
  90. printf("\n");
  91. ldr_show(root);
  92. printf("\n");
  93. create_clue(root);
  94. clue_show(root);
  95. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/892028
推荐阅读
相关标签
  

闽ICP备14008679号