当前位置:   article > 正文

Java实现平衡二叉树_java 手写平衡二叉树

java 手写平衡二叉树

创建平衡二叉树,主要是一旦出现不平衡状态如何更改,这个一直是一个比较晕的,什么左旋右旋很乱。下面跟大家说下如何比较好理解的来进行平衡,阅读本文前需要先明白,不平衡的四种情况即,左左,左右,右左,右右四种情况,如果不懂的,可以自己百度,关于这个很多理解。本文主要是针对对于左旋和右旋理解不了或者想学习用java编写的代码。

其实不管怎么转,其实只是重新改变不平衡节点的左右子树,因此,我们只需要记住不平衡节点的左右子树的左右子树分别该如何得到,就可以。

1、左左情况。

因为左边的过长,所以要吧左边的过长的部分从中间折断,这样就可以把3层节点来弄成两层,这样就可以平衡。

(图片来自网络,侵删)

因此可以看出,新的左子树的左子树为原不平衡节点K2的左子树的左子树的左子树。新的右子树的左子树为不平衡点的左子树的右子树,新右子树的右子树为不平衡点的右子树,右子树的节点为不平衡节点的值,不平衡点值为原不平衡点左子树的值。

代码化为:

  1. BalancedBinaryNode newleftnode=balancedBinaryNode.left.left;
  2. BalancedBinaryNode newrightnode=new BalancedBinaryNode();
  3. newrightnode.left=balancedBinaryNode.left.right;
  4. newrightnode.right=balancedBinaryNode.right;
  5. newrightnode.data=balancedBinaryNode.data;
  6. balancedBinaryNode.data=balancedBinaryNode.left.data;
  7. balancedBinaryNode.left=newleftnode;
  8. balancedBinaryNode.right=newrightnode;

分析:因为左边过长,所以要折半,即把不平衡点左子树的值作为这部分树的根,那么,根的左子树,也就是新的左子树,所有值都比根要小,而新的右子树要比根大。所以,比根小的 只有根的左子树比他小,所以:新的左子树就是新根原来的左子树:即BalancedBinaryNode newleftnode=balancedBinaryNode.left.left;。剩下的三部分很好理解,新根原来的右子树、原根的右子树、原根的大小关系,很明显:新根原来的右子树<原根<原根的右子树,所以将原根作为新根的右子树,也就是新的右子树,将新根的右子树作为新右子树的左子树,将原根的右子树作为新子树的右子树,

2、右右情况

与左左情况原理相同,只需要左换右即可

3、左右

先附上旋转图(来自网络,侵删)

说实话,这个做法很完美,但是,理解起来有点困难,尤其是没空间想象能力较差。那我们现在来看一看能不能从结果找到什么。

首先,既然是左右了,那么一定是存在 不平衡点、不平衡点左孩子、不平衡点左孩子的有孩子  (原因是左右就是左子树的右子树插入孩子),很显然大小关系:不平衡点左孩子<不平衡点左孩子的右孩子<不平衡点,所以平衡成一颗新树就是  新根节点一定是不平衡节点的左孩子的右孩子,那么新左子树是不平衡点的左孩子,新右子树是不平衡点   ok,来看左右子节点的左右子树分别是啥,先看新左子树的左子树,比新左子树小的 只有原来树中比它小的,那就是原树种不平衡点左子树(新左子树)的左子树,同理,新右子树的右子树就是原不平衡点(新右子树)的右子树。现在还剩下不平衡点的左子树的右子树(新根节点)的左右子树,先看左子树,小于新根节点,所以只能是位于新左子树的一部分,但是,它由于属于新左子树原来右子树的一部分,所以大于新左子树,所以为左子树的右子树,同理,新根节点的原右子树就是右子树的左子树。

所以结论就是:

根节点的值是:不平衡点的左子树的右子树的值

根的左子树节点是:不平衡点的左子树的值

根的右子树节点是:不平衡点的值

新左子树的左子树是:不平衡点的左子树的左子树

新左子树的右子树是:不平衡点左子树的右子树的左子树

新右子树的左子树是:不平衡点左子树的右子树的右子树

新右子树的右子树是:不平衡点的右子树

  1. BalancedBinaryNode newleftnode=new BalancedBinaryNode();
  2. BalancedBinaryNode newrightnode=new BalancedBinaryNode();
  3. newleftnode.data=balancedBinaryNode.left.data;
  4. newleftnode.left=balancedBinaryNode.left.left;
  5. newleftnode.right=balancedBinaryNode.left.right.left;
  6. newrightnode.data=balancedBinaryNode.data;
  7. newrightnode.left=balancedBinaryNode.left.right.right;
  8. newrightnode.right=balancedBinaryNode.right;
  9. balancedBinaryNode.data=balancedBinaryNode.left.right.data;
  10. balancedBinaryNode.left=newleftnode;
  11. balancedBinaryNode.right=newrightnode;

4、右左理解方式一样

5、下面放入整体代码:

  1. package DataStruct;
  2. import java.util.LinkedList;
  3. import java.util.Queue;
  4. public class BalancedBinaryTree {
  5. public static class BalancedBinaryNode{
  6. public int data;
  7. public BalancedBinaryNode left;
  8. public BalancedBinaryNode right;
  9. public int ceng ;
  10. public int du;
  11. }
  12. public static BalancedBinaryNode init(int data){
  13. BalancedBinaryNode root=new BalancedBinaryNode();
  14. root.data=data;
  15. root.left=null;
  16. root.right=null;
  17. root.du=0;
  18. return root;
  19. }
  20. public static void add(BalancedBinaryNode root,int data){
  21. BalancedBinaryNode temp=root;
  22. BalancedBinaryNode newNode=new BalancedBinaryNode();
  23. newNode.left=null;newNode.right=null;newNode.data=data;
  24. while(true){
  25. if(data<temp.data){
  26. if(temp.left!=null){
  27. temp=temp.left;
  28. }else{
  29. temp.left=newNode;
  30. return ;
  31. }
  32. }else if(data>temp.data){
  33. if(temp.right!=null){
  34. temp=temp.right;
  35. }else{
  36. temp.right=newNode;
  37. return ;
  38. }
  39. }else{
  40. return;
  41. }
  42. }
  43. }
  44. public static void balance(BalancedBinaryNode root,int data){
  45. Queue<BalancedBinaryNode> queue=new LinkedList<>();
  46. if(root==null){
  47. return ;
  48. }
  49. queue.add(root);
  50. root.ceng=1;
  51. BalancedBinaryNode balancedBinaryNode;
  52. while(queue.size()!=0){
  53. balancedBinaryNode=queue.poll();
  54. int leftheaght=balancedBinaryNode.left==null?0:getDu(balancedBinaryNode.left);
  55. int rightheaght=balancedBinaryNode.right==null?0:getDu(balancedBinaryNode.right);
  56. //该节点平衡
  57. if(Math.abs(leftheaght-rightheaght)<2){
  58. if(balancedBinaryNode.left!=null){
  59. queue.add(balancedBinaryNode.left);
  60. }
  61. if(balancedBinaryNode.right!=null){
  62. queue.add(balancedBinaryNode.right);
  63. }
  64. }
  65. //否则不平衡
  66. else{
  67. if(leftheaght>rightheaght){
  68. if(data<balancedBinaryNode.left.data){
  69. leftAndLeft(balancedBinaryNode);
  70. }else{
  71. leftandright(balancedBinaryNode);
  72. }
  73. }else{
  74. if(data<balancedBinaryNode.right.data){
  75. System.out.println("右左");
  76. rightandleft(balancedBinaryNode);
  77. }else{
  78. rightandright(balancedBinaryNode);
  79. }
  80. }
  81. }
  82. }
  83. }
  84. //左左的平衡
  85. public static void leftAndLeft(BalancedBinaryNode balancedBinaryNode){
  86. BalancedBinaryNode newleftnode=balancedBinaryNode.left.left;
  87. BalancedBinaryNode newrightnode=new BalancedBinaryNode();
  88. newrightnode.left=balancedBinaryNode.left.right;
  89. newrightnode.right=balancedBinaryNode.right;
  90. newrightnode.data=balancedBinaryNode.data;
  91. balancedBinaryNode.data=balancedBinaryNode.left.data;
  92. balancedBinaryNode.left=newleftnode;
  93. balancedBinaryNode.right=newrightnode;
  94. }
  95. //右右的平衡
  96. public static void rightandright(BalancedBinaryNode balancedBinaryNode){
  97. BalancedBinaryNode newleftnnode=new BalancedBinaryNode();
  98. BalancedBinaryNode newrightnode=balancedBinaryNode.right.right;
  99. newleftnnode.left=balancedBinaryNode.left;
  100. newleftnnode.right=balancedBinaryNode.right.left;
  101. newleftnnode.data=balancedBinaryNode.data;
  102. balancedBinaryNode.data=balancedBinaryNode.right.data;
  103. balancedBinaryNode.left=newleftnnode;
  104. balancedBinaryNode.right=newrightnode;
  105. }
  106. //左右的平衡
  107. public static void leftandright(BalancedBinaryNode balancedBinaryNode){
  108. BalancedBinaryNode newleftnode=new BalancedBinaryNode();
  109. BalancedBinaryNode newrightnode=new BalancedBinaryNode();
  110. newleftnode.data=balancedBinaryNode.left.data;
  111. newleftnode.left=balancedBinaryNode.left.left;
  112. newleftnode.right=balancedBinaryNode.left.right.left;
  113. newrightnode.data=balancedBinaryNode.data;
  114. newrightnode.left=balancedBinaryNode.left.right.right;
  115. newrightnode.right=balancedBinaryNode.right;
  116. balancedBinaryNode.data=balancedBinaryNode.left.right.data;
  117. balancedBinaryNode.left=newleftnode;
  118. balancedBinaryNode.right=newrightnode;
  119. }
  120. //右左的旋转
  121. public static void rightandleft(BalancedBinaryNode balancedBinaryNode){
  122. BalancedBinaryNode newleftnode=new BalancedBinaryNode();
  123. BalancedBinaryNode newrightnode=new BalancedBinaryNode();
  124. newleftnode.data=balancedBinaryNode.data;
  125. newleftnode.left=balancedBinaryNode.left;
  126. newleftnode.right=balancedBinaryNode.right.left.left;
  127. newrightnode.data=balancedBinaryNode.right.data;
  128. newrightnode.left=balancedBinaryNode.right.left.right;
  129. newrightnode.right=balancedBinaryNode.right.right;
  130. balancedBinaryNode.data=balancedBinaryNode.right.left.data;
  131. balancedBinaryNode.left=newleftnode;
  132. balancedBinaryNode.right=newrightnode;
  133. }
  134. //获得某个节点的度
  135. public static int getDu(BalancedBinaryNode binaryNode){
  136. int result=0;
  137. if(binaryNode.left==null && binaryNode.right==null){
  138. result=1;
  139. }else if(binaryNode.left==null){
  140. result=1+getDu(binaryNode.right);
  141. }else if(binaryNode.right==null){
  142. result=1+getDu(binaryNode.left);
  143. }else{
  144. result=1+Math.max(getDu(binaryNode.left),getDu(binaryNode.right));
  145. }
  146. return result;
  147. }
  148. //
  149. public static void show(BalancedBinaryNode root){
  150. Queue<BalancedBinaryNode> queue=new LinkedList<>();
  151. if(root==null){
  152. System.out.println("空的");
  153. return ;
  154. }
  155. queue.add(root);
  156. root.ceng=1;
  157. BalancedBinaryNode balancedBinaryNode;
  158. while(queue.size()!=0){
  159. balancedBinaryNode=queue.poll();
  160. if(balancedBinaryNode.left!=null){
  161. balancedBinaryNode.left.ceng=balancedBinaryNode.ceng+1;
  162. queue.add(balancedBinaryNode.left);
  163. }
  164. if(balancedBinaryNode.right!=null){
  165. balancedBinaryNode.right.ceng=balancedBinaryNode.ceng+1;
  166. queue.add(balancedBinaryNode.right);
  167. }
  168. System.out.println("数据为:"+balancedBinaryNode.data+" 所在层数 "+balancedBinaryNode.ceng);
  169. }
  170. }
  171. }

 

6、测试代码和结果

  1. package TestMain;
  2. import DataStruct.BalancedBinaryTree;
  3. import DataStruct.BalancedBinaryTree.BalancedBinaryNode;
  4. public class Main {
  5. public static void main(String args[]) {
  6. // int data[]={62, 88, 58, 47, 35, 73, 51, 99, 37, 93};
  7. int data[]={1,2,3,4,5,6,7,8};
  8. BalancedBinaryNode root=BalancedBinaryTree.init(data[0]);
  9. for(int i=1;i<data.length;i++){
  10. BalancedBinaryTree.add(root, data[i]);
  11. BalancedBinaryTree.balance(root,data[i]);
  12. }
  13. BalancedBinaryTree.show(root);
  14. }
  15. }

数据为:5 所在层数 1
数据为:3 所在层数 2
数据为:6 所在层数 2
数据为:2 所在层数 3
数据为:4 所在层数 3
数据为:7 所在层数 3
数据为:1 所在层数 4
数据为:8 所在层数 4
 

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

闽ICP备14008679号