剑指offer之二叉搜索树和双向链表

举报
chenyu 发表于 2021/07/26 23:03:23 2021/07/26
【摘要】 1 问题 比如我们搜索二叉树如下,我们需要变成双向链表               2 分析 我们知道这个变成双向链接的时候是按照树的中序遍历打印的,我们只需要在中序遍历打印的时候操作该节点,我们可以用临时变量保存这个节点,同时我们也需要单独增加一个链表节点变量,我们需要保证这个节点的左边...

1 问题

比如我们搜索二叉树如下,我们需要变成双向链表
 

 

 

 

 

 

 

2 分析

我们知道这个变成双向链接的时候是按照树的中序遍历打印的,我们只需要在中序遍历打印的时候操作该节点,我们可以用临时变量保存这个节点,同时我们也需要单独增加一个链表节点变量,我们需要保证这个节点的左边指向是该链表节点,然后该链表节点的右指向是这个节点,然后我们再把这个节点赋值给这个链表节点,就这样一直移动下去即可。

 

 

 

 

 

3 代码实现

我这里以下面的搜索二叉树进行操作的


  
  1. 4
  2. 2 6
  3. 1 3 5 7

  
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef struct Tree
  4. {
  5. int value;
  6. struct Tree* left;
  7. struct Tree* right;
  8. } Tree;
  9. /*
  10. * 把搜索二叉树转成双向链表,我们按照中序遍历
  11. */
  12. void convertNode(Tree* node, Tree** lastNodeList)
  13. {
  14. if (node == NULL)
  15. return;
  16. Tree* pCurrent = node;
  17. if (pCurrent->left != NULL)
  18. {
  19. convertNode(pCurrent->left, lastNodeList);
  20. }
  21. //这里就要进行我们每个节点的前后正确的指向了
  22. pCurrent->left = *lastNodeList;
  23. if (*lastNodeList != NULL)
  24. {
  25. (*lastNodeList)->right = pCurrent;
  26. }
  27. *lastNodeList = pCurrent;
  28. if (pCurrent->right != NULL)
  29. {
  30. convertNode(pCurrent->right, lastNodeList);
  31. }
  32. }
  33. /*
  34. * 把翻转好的双向链表尾巴节点移动到链表头
  35. */
  36. Tree* convert(Tree* node, Tree* lastNodeList)
  37. {
  38. if (node == NULL || lastNodeList == NULL)
  39. {
  40. printf("node is NULL or lastNodeList is NULL\n");
  41. return NULL;
  42. }
  43. Tree* last = NULL;
  44. convertNode(node, &lastNodeList);
  45. //因为这个时候lastNodeList已经到了双向链表尾巴,我们需要移动到链表头
  46. Tree* headNodeList = lastNodeList;
  47. while (headNodeList != NULL && headNodeList->left != NULL)
  48. {
  49. headNodeList = headNodeList -> left;
  50. }
  51. return headNodeList;
  52. }
  53. /*
  54. * 双向链表从左到右打印
  55. */
  56. void printRightList(Tree* headNodeList)
  57. {
  58. if (headNodeList == NULL)
  59. {
  60. printf("headNodeList is NULL\n");
  61. return;
  62. }
  63. printf("we will print list from left to right\n");
  64. Tree* pCurrent = headNodeList;
  65. while (pCurrent != NULL)
  66. {
  67. printf("value is %d\n", pCurrent->value);
  68. pCurrent = pCurrent->right;
  69. }
  70. }
  71. /*
  72. * 双向链表从右到左打印
  73. */
  74. void printLeftList(Tree* headNodeList)
  75. {
  76. if (headNodeList == NULL)
  77. {
  78. printf("headNodeList is NULL\n");
  79. return;
  80. }
  81. printf("we will print list from right to left\n");
  82. Tree* pCurrent = headNodeList;
  83. //先把链表头结点移动为链表的尾巴
  84. while (pCurrent->right != NULL)
  85. {
  86. //printf("value is %d\n", pCurrent->value);
  87. pCurrent = pCurrent->right;
  88. }
  89. //pCurrent = pCurrent->left;
  90. while (pCurrent != NULL)
  91. {
  92. printf("value is %d\n", pCurrent->value);
  93. pCurrent = pCurrent->left;
  94. }
  95. }
  96. int main(void)
  97. {
  98. Tree *node1 , *node2 , *node3, *node4, *node5, *node6, *node7;
  99. node1 = (Tree *)malloc(sizeof(Tree));
  100. node2 = (Tree *)malloc(sizeof(Tree));
  101. node3 = (Tree *)malloc(sizeof(Tree));
  102. node4 = (Tree *)malloc(sizeof(Tree));
  103. node5 = (Tree *)malloc(sizeof(Tree));
  104. node6 = (Tree *)malloc(sizeof(Tree));
  105. node7 = (Tree *)malloc(sizeof(Tree));
  106. node1->value = 4;
  107. node2->value = 2;
  108. node3->value = 6;
  109. node4->value = 1;
  110. node5->value = 3;
  111. node6->value = 5;
  112. node7->value = 7;
  113. node1->left = node2;
  114. node1->right = node3;
  115. node2->left = node4;
  116. node2->right = node5;
  117. node3->left = node6;
  118. node3->right = node7;
  119. node4->left = NULL;
  120. node4->right = NULL;
  121. node5->left = NULL;
  122. node5->right = NULL;
  123. node6->left = NULL;
  124. node6->right = NULL;
  125. node7->left = NULL;
  126. node7->right = NULL;
  127. Tree* list = (Tree *)malloc(sizeof(Tree));
  128. if (!list)
  129. {
  130. printf("malloc list fail\n");
  131. return -1;
  132. }
  133. Tree* firstNodeList = NULL;
  134. //convertNode(node1, &list);
  135. firstNodeList = convert(node1, list);
  136. if (firstNodeList == NULL)
  137. {
  138. printf("firstNodeList is NULL\n");
  139. return -1;
  140. }
  141. printRightList(firstNodeList);
  142. printLeftList(firstNodeList);
  143. return 0;
  144. }

 

 

 

 

4 运行结果


  
  1. we will print list from left to right
  2. value is 0
  3. value is 1
  4. value is 2
  5. value is 3
  6. value is 4
  7. value is 5
  8. value is 6
  9. value is 7
  10. we will print list from right to left
  11. value is 7
  12. value is 6
  13. value is 5
  14. value is 4
  15. value is 3
  16. value is 2
  17. value is 1
  18. value is 0

 

文章来源: chenyu.blog.csdn.net,作者:chen.yu,版权归原作者所有,如需转载,请联系作者。

原文链接:chenyu.blog.csdn.net/article/details/102493455

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。