1. 二叉树

二叉树结构:image.png

  1. 概念:任何一个节点的子节点数量不超过2
  2. 特点:子节点分左节点和右节点。左右节点不能随意颠倒位置image.png
  3. 满二叉树:所有叶子节点都在最后一层,而且节点的总数为2-1,n是树的高度
  4. 完全二叉树:所有叶子节点都在最后一层或倒数第二层,且最后一层的叶子节点在左边连续,倒数第二节的叶子节点在右边连续
  5. 遍历二叉树:image.png

    前序遍历:1 2 4 5 3 6 7 中序遍历:4 2 5 1 6 3 7 后序遍历:4 5 2 6 7 3 1 层序遍历:1 2 3 4 5 6 7

前序遍历、前序遍历,后序遍历和层序遍历,以及其他操作

  1. package pegatron.sw.learn;
  2. import java.util.LinkedList;
  3. import java.util.Queue;
  4. public class TreeNode {
  5. //数的权(值)
  6. int data;
  7. //创建左儿子
  8. TreeNode leftNode;
  9. //创建右儿子
  10. TreeNode rightNode;
  11. public TreeNode() {
  12. }
  13. public TreeNode(int data) {
  14. this.data=data;
  15. }
  16. public void setLeftNode(TreeNode leftNode) {
  17. this.leftNode = leftNode;
  18. }
  19. public void setRightNode(TreeNode rightNode) {
  20. this.rightNode = rightNode;
  21. }
  22. //获取二叉树高度
  23. public int depth(TreeNode node){
  24. if(node != null){
  25. int l=depth(node.leftNode);
  26. int r=depth(node.rightNode);
  27. if(l>r){
  28. return l+1;
  29. }else{
  30. return r+1;
  31. }
  32. }
  33. return 0;
  34. }
  35. //前序遍历(递归方法) 根节点 -> 左节点 -> 左子节点 -> 右子节点 -> 右节点-> 左子节点 -> 右子节点
  36. public void frontShow() {
  37. System.out.println(data);//先打印自己
  38. //在打印左节点
  39. if(leftNode != null){
  40. leftNode.frontShow();
  41. }
  42. //在遍历右节点
  43. if(rightNode != null){
  44. rightNode.frontShow();
  45. }
  46. }
  47. //中序遍历(递归方法)左节点 -> 根节点 ->右节点
  48. public void middleShow() {
  49. //先遍历左节点
  50. if(leftNode != null){
  51. leftNode.middleShow();
  52. }
  53. //打印当前节点数据
  54. System.out.println(data);
  55. //在遍历右节点
  56. if(rightNode != null){
  57. rightNode.middleShow();
  58. }
  59. }
  60. //后序遍历(递归方法) 左节点 -> 右节点 -> 根节点
  61. public void afterShow() {
  62. //先遍历左节点
  63. if(leftNode != null){
  64. leftNode.afterShow();
  65. }
  66. //在遍历右节点
  67. if(rightNode != null){
  68. rightNode.afterShow();
  69. }
  70. //后打印当前节点
  71. System.out.println(data);
  72. }
  73. //层序遍历(递归方法) 根节点 -> 左节点 -> 右节点-> 左子节点 -> 右子节点 -> 左子节点 -> 右子节点
  74. public void levelShow(TreeNode node) {
  75. if(node == null) return;
  76. Queue<TreeNode> queue=new LinkedList<TreeNode>();
  77. queue.add(node);
  78. while(!queue.isEmpty()){
  79. TreeNode root=queue.poll();
  80. System.out.println(root.data);
  81. if(root.leftNode != null){
  82. queue.add(root.leftNode);
  83. }
  84. if(root.rightNode!=null){
  85. queue.add(root.rightNode);
  86. }
  87. }
  88. }
  89. //二叉树的镜像
  90. public TreeNode jingxiang(TreeNode node){
  91. if(node == null){
  92. return null;
  93. }
  94. TreeNode root=node.leftNode;
  95. node.leftNode=node.rightNode;
  96. node.rightNode=root;
  97. jingxiang(node.leftNode);
  98. jingxiang(node.rightNode);
  99. return node;
  100. }
  101. //前需查找
  102. public TreeNode frontSearch(int i) {
  103. //先创建一个值作为找到的值
  104. TreeNode value=null;
  105. //判断当前值是否与要查的值一样
  106. if(this.data == i){
  107. return this;//如果一样则返回
  108. //如果不一样
  109. }else {
  110. //就先查询左节点中又是否有要查的值
  111. if(leftNode != null){
  112. //有可能查到,也可能查不到,查不到的话,value还是一个null
  113. value=leftNode.frontSearch(i);
  114. }
  115. //如果不为空,说明左节点中已经查到,
  116. if(value != null){
  117. return value;
  118. }
  119. //如果左节点没有就查询右节点
  120. if(rightNode != null){
  121. value=rightNode.frontSearch(i);
  122. }
  123. }
  124. return value;
  125. }
  126. //中序查找
  127. public TreeNode midSearch(int i) {
  128. //先创建一个值作为找到的值
  129. TreeNode value=null;
  130. //就先查询左节点中又是否有要查的值
  131. if(leftNode != null){
  132. //有可能查到,也可能查不到,查不到的话,value还是一个null
  133. value=leftNode.midSearch(i);
  134. }
  135. //如果不为空,说明左节点中已经查到,
  136. if(value != null){
  137. return value;
  138. }
  139. if(this.data == i){
  140. return this;
  141. }
  142. //如果左节点没有就查询右节点
  143. if(rightNode != null){
  144. value=rightNode.midSearch(i);
  145. }
  146. return value;
  147. }
  148. //后序查找
  149. public TreeNode afterSearch(int i) {
  150. //先创建一个值作为找到的值
  151. TreeNode value=null;
  152. if(leftNode != null){
  153. //有可能查到,也可能查不到,查不到的话,value还是一个null
  154. value=leftNode.midSearch(i);
  155. }
  156. //如果不为空,说明左节点中已经查到,
  157. if(value != null){
  158. return value;
  159. }
  160. //如果左节点没有就查询右节点
  161. if(rightNode != null){
  162. value=rightNode.midSearch(i);
  163. }
  164. //如果不为空,说明右节点中已经查到,
  165. if(value != null){
  166. return value;
  167. }
  168. if(this.data == i){
  169. return this;
  170. }
  171. return value;
  172. }
  173. /**删除树
  174. * @param i 要删除的节点的数据
  175. *
  176. * 逻辑:先判断左节点的数据是否是要删除的数据,如果是则让左儿子为空即为删除。右儿子同理
  177. * 如果上面条件不符合,则递归检查删除左右儿子
  178. *
  179. */
  180. public void delete(int i) {
  181. TreeNode parent=this;
  182. //判断左儿子
  183. if(parent.leftNode != null && parent.leftNode.data ==i){
  184. parent.leftNode=null;
  185. return;
  186. }
  187. //判断右儿子
  188. if(parent.rightNode!= null &&parent.rightNode.data == i){
  189. parent.rightNode=null;
  190. return;
  191. }
  192. //递归检查并删除左儿子
  193. parent=leftNode;
  194. if(parent != null){
  195. parent.delete(i);
  196. }
  197. //递归检查并删除左儿子
  198. parent=rightNode;
  199. if(parent != null){
  200. parent.delete(i);
  201. }
  202. }
  203. }

顺序存储二叉树

  1. 顺序存储的二叉树通常情况只考虑完全二叉树
  2. 特点:
    1. 第n个元素的左子节点是:2*n+1
    2. 第n个元素的右子节点是:2*n+2
    3. 第n个元素的父节点是:(n-1)/2