二叉树的遍历(前序遍历、中序遍历、后序遍历)

短命女 2022-07-15 16:07 473阅读 0赞

二叉树

在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作 左子树 和 右子树。

树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构。

树和二叉树的2个主要差别:

  1. 树中结点的最大度数没有限制,而二叉树结点的最大度数为2;
  2. 树的结点无左、右之分,而二叉树的结点有左、右之分

二叉树也是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:

(1)空二叉树 无根节点的二叉树

(2)只有一个根结点的二叉树

(3)只有右子树 无左子树

(4)只有左子树 无右子树

(5)完全二叉树

二叉树的遍历

这里写图片描述

前序遍历

前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。
若二叉树为空则结束返回,否则:
(1)访问根结点。
(2)前序遍历左子树。
(3)前序遍历右子树 。
需要注意的是:遍历左右子树时仍然采用前序遍历方法。
已知后序遍历和中序遍历,就能确定前序遍历。

  1. public static void beforeDisplay(Node parent) {
  2. if(parent==null){
  3. return;
  4. }
  5. Node left=parent.getLeft();
  6. Node right=parent.getRight();
  7. //先遍历中间节点,再递归遍历左右 遍历顺序(中、左、右)
  8. System.out.println(parent);
  9. beforeDisplay(left);
  10. beforeDisplay(right);
  11. }
  12. 上图前序遍历的结果如下:
  13. [value: a , index: 4 ]
  14. [value: b , index: 8 ]
  15. [value: d , index: 9 ]
  16. [value: e , index: 7 ]
  17. [value: h , index: 5 ]
  18. [value: i , index: 6 ]
  19. [value: c , index: 3 ]
  20. [value: f , index: 2 ]
  21. [value: g , index: 1 ]

中序遍历

中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树。
在遍历左、右子树时,仍然先遍历左子树,再访问根结点,最后遍历右子树。
即:
若二叉树为空则结束返回
否则:
(1)中序遍历左子树。
(2)访问根结点。
(3)中序遍历右子树。
需要注意的是:遍历左右子树时仍然采用中序遍历方法。
如果一棵二叉排序树的节点值是数值,中序遍历的结果为升序排列的数组。
可以利用该性质检测一棵树是否为二叉排序数。
已知前序遍历和后序遍历,不能确定唯一的中序遍历。

  1. public static void centerDisplay(Node parent) {
  2. if(parent==null){
  3. return;
  4. }
  5. Node left=parent.getLeft();
  6. Node right=parent.getRight();
  7. centerDisplay(left);
  8. //先遍历左节点,再递归遍历中右 遍历顺序(左、中、右)
  9. System.out.println(parent);
  10. centerDisplay(right);
  11. }
  12. 上图中序遍历的结果如下:
  13. [value: d , index: 9 ]
  14. [value: b , index: 8 ]
  15. [value: e , index: 7 ]
  16. [value: i , index: 6 ]
  17. [value: h , index: 5 ]
  18. [value: a , index: 4 ]
  19. [value: c , index: 3 ]
  20. [value: f , index: 2 ]
  21. [value: g , index: 1 ]

后序遍历

后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。
即:若二叉树为空则结束返回,
否则:
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根结点
已知前序遍历和中序遍历,就能确定后序遍历。

  1. public static void afterDisplay(Node parent) {
  2. if(parent==null){
  3. return;
  4. }
  5. Node left=parent.getLeft();
  6. Node right=parent.getRight();
  7. afterDisplay(left);
  8. afterDisplay(right);
  9. //先遍历左右,后遍历中 遍历顺序(左、右、中)
  10. System.out.println(parent);
  11. }
  12. 上图后序遍历的结果如下:
  13. [value: d , index: 9 ]
  14. [value: i , index: 6 ]
  15. [value: h , index: 5 ]
  16. [value: e , index: 7 ]
  17. [value: b , index: 8 ]
  18. [value: g , index: 1 ]
  19. [value: f , index: 2 ]
  20. [value: c , index: 3 ]
  21. [value: a , index: 4 ]

以下是二叉树的结构、插入、以及遍历 (完整)

  1. public class BinaryTreeDemo {
  2. //二叉树结构类
  3. static class Node{
  4. //左节点
  5. Node left;
  6. //右节点
  7. Node right;
  8. //值
  9. String value;
  10. //键
  11. Integer key;
  12. public Node getLeft() {
  13. return left;
  14. }
  15. public void setLeft(Node left) {
  16. this.left = left;
  17. }
  18. public Node getRight() {
  19. return right;
  20. }
  21. public void setRight(Node right) {
  22. this.right = right;
  23. }
  24. public Node(int key ,String value){
  25. this.key=key;
  26. this.value=value;
  27. }
  28. public Node(){
  29. }
  30. public String getValue() {
  31. return value;
  32. }
  33. public void setValue(String value) {
  34. this.value = value;
  35. }
  36. public int getKey() {
  37. return key;
  38. }
  39. public void setKey(int key) {
  40. this.key = key;
  41. }
  42. @Override
  43. public String toString() {
  44. return "[value: "+this.getValue()+" , index: "+this.getKey()+" ]";
  45. }
  46. }
  47. //二叉树管理类、管理节点如何分配
  48. static class NodeManager{
  49. private static Node root;
  50. public static void setNode(Node parent,Node node){
  51. //二叉树根是否是为空
  52. if(root==null){
  53. //设置第一个插入的节点为根节点
  54. root=node;
  55. return;
  56. }
  57. Node left=parent.getLeft();
  58. Node right=parent.getRight();
  59. //插入的节点key 比 父节点 大 (即:大的挂左边,小的挂右边 )
  60. if(parent.getKey()<node.getKey()){
  61. //比父节点大,挂在父节点的左节点 ,前提是父节点左边无节点可比较了,否则需要递归比较
  62. if(left==null){
  63. parent.setLeft(node);
  64. }else{
  65. //递归左节点
  66. setNode(left,node);
  67. }
  68. }else{
  69. if(right==null){
  70. parent.setRight(node);
  71. }else{
  72. //递归右节点
  73. setNode(right,node);
  74. }
  75. }
  76. }
  77. public static void beforeDisplay(Node parent) {
  78. if(parent==null){
  79. return;
  80. }
  81. Node left=parent.getLeft();
  82. Node right=parent.getRight();
  83. System.out.println(parent);
  84. beforeDisplay(left);
  85. beforeDisplay(right);
  86. }
  87. public static void centerDisplay(Node parent) {
  88. if(parent==null){
  89. return;
  90. }
  91. Node left=parent.getLeft();
  92. Node right=parent.getRight();
  93. centerDisplay(left);
  94. System.out.println(parent);
  95. centerDisplay(right);
  96. }
  97. public static void afterDisplay(Node parent) {
  98. if(parent==null){
  99. return;
  100. }
  101. Node left=parent.getLeft();
  102. Node right=parent.getRight();
  103. afterDisplay(left);
  104. afterDisplay(right);
  105. System.out.println(parent);
  106. }
  107. }
  108. public static void main(String[] args) {
  109. String arr [] ={
  110. "a","b","c","d","e","f","g","h","i"};
  111. int key [] ={
  112. 4,8,3,9,7,2,1,5,6};
  113. //按照数组索引顺序将键值插入到二叉树结构中
  114. for(int i =0 ;i<arr.length;i++){
  115. String c = arr[i];
  116. int k = key[i];
  117. NodeManager.setNode(NodeManager.root,new Node(k,c));
  118. /**
  119. * 第一个插入的节点 key 是4,value 是 a
  120. 首先二叉树需要有有根节点,第一个节点为跟节点
  121. 第二个节点 key 是 8,value 是 b
  122. key比根节点大,遍历根节点的左节点,根节点的左节点为null, 所以第二节点为根节点的左节点,
  123. 否则递归根节点的左节点的左节点,进行比较,插入节点的key比该节点的key 大挂置左边,小挂置右边(前提是左或者是右为null)以此类推。
  124. */
  125. }
  126. //遍历
  127. NodeManager.beforeDisplay(NodeManager.root);
  128. System.out.println("end");
  129. NodeManager.centerDisplay(NodeManager.root);
  130. System.out.println("end");
  131. NodeManager.afterDisplay(NodeManager.root);
  132. System.out.println("end");
  133. }
  134. }

遍历练习

二叉树的先序遍历为:F B A C D E G H,
中序遍历为:A B D C E F G H ,
该二叉树的后序遍历为()

A:A D EC B H G F
B:A B D E C G H F
C:G H A D E C B F
D:H G A D E C B F

发表评论

表情:
评论列表 (有 0 条评论,473人围观)

还没有评论,来说两句吧...

相关阅读