From 784154953a6ed3c77ef87af73b8156f5186c7773 Mon Sep 17 00:00:00 2001 From: myd <815777051@qq.com> Date: Wed, 27 Jul 2022 20:19:25 +0800 Subject: [PATCH 1/3] new branch --- balanceTree/src/main/java/AVL.java | 87 ++++++++++--------- balanceTree/src/main/java/BPlusTree.java | 3 - .../src/main/java/{BRT.java => RBT.java} | 4 +- balanceTree/src/test/java/RBTTest.java | 4 +- 4 files changed, 49 insertions(+), 49 deletions(-) rename balanceTree/src/main/java/{BRT.java => RBT.java} (99%) diff --git a/balanceTree/src/main/java/AVL.java b/balanceTree/src/main/java/AVL.java index 2002fb3..b943fcc 100644 --- a/balanceTree/src/main/java/AVL.java +++ b/balanceTree/src/main/java/AVL.java @@ -8,50 +8,63 @@ import java.util.List; public class AVL { private Node root; + + class Node { + int data; + int high; + Node left; + Node right; + Node parent; + public Node(int val){ + high = 0; + data = val; + } + } + /* RR_rotate: LL 型右旋平衡; */ private Node LL_rotate(Node node){//被旋转的节点 - Node father = node.father; + Node parent = node.parent; Node left = node.left; Node lr = left.right; - if(father == null){ + if(parent == null){ root = left; }else{ - if(father.left == node){ - father.left = left; + if(parent.left == node){ + parent.left = left; }else{//father.right = node - father.right = left; + parent.right = left; } } left.right = node; - left.father = father; + left.parent = parent; node.left = lr; - node.father = left; - if(lr!= null)lr.father = node; + node.parent = left; + if(lr!= null)lr.parent = node; updateHeight(node); updateHeight(left); return left; } //RR型,左旋平衡; private Node RR_rotate(Node node){//parent - Node father = node.father; + Node parent = node.parent; Node right = node.right; Node rl = right.left; - if(father == null){ + if(parent == null){ root = right; }else{ - if(father.left == node){ - father.left = right; + if(parent.left == node){ + parent.left = right; }else{ - father.right = right; + parent.right = right; } } node.right = rl; - node.father = right; - if(rl!= null)rl.father = node; + node.parent = right; + if(rl!= null)rl.parent = node; right.left = node; - right.father = father; + right.parent = parent; updateHeight(node); updateHeight(right); return right; @@ -64,18 +77,7 @@ public class AVL { LL_rotate(node.right); return RR_rotate(node); } - class Node { - int data; - int high; - Node left; - Node right; - Node father; - public Node(int val){ - high = 0; - data = val; - } - } - public int getNodeHeight(Node node){ + int getNodeHeight(Node node){ if(node == null)return -1; return node.high; } @@ -89,14 +91,14 @@ public class AVL { if(!insertSuccess)return;//数据与tree中的数据重复,会插入失败; //调整temp(node.father)->root 路径之间节点的高度;同时需要判断,需不需要调整树的平衡; // 条件满足:leftHigh - rightHigh == +2 /-2;=== > 需要调整树的平衡 - insertBalance(node.father); + insertBalance(node.parent); } public void deleteVal(int val){ Node target = searchNode(val,root); if(target == null)return; Node left = target.left; Node right = target.right; - Node parent = target.father; + Node parent = target.parent; if(left == null && right == null){//case 1 :没有左右子节点 if(parent == null){ root=null; @@ -106,14 +108,14 @@ public class AVL { }else if(left != null && right == null){//case 2 :只有左节点 if(parent == null){ root = left; - root.father = null; + root.parent = null; }else{ deleteNode(target,parent,left); } }else if(left == null && right != null){//case 3 :只有右节点 if(parent == null){ root = right; - root.father = null; + root.parent = null; }else{ deleteNode(target,parent,right); } @@ -125,7 +127,7 @@ public class AVL { } //将找到的节点的值,替换被删除的节点数据,删除lr节点; if(lr == null){ - left.father = parent; + left.parent = parent; if(parent == null){ left=root; }else{ @@ -134,11 +136,11 @@ public class AVL { deleteNode(target,parent,left); } left.right =right; - right.father = left; + right.parent = left; parent = left;//从left节点开始检查左右两侧tree的高度是否平衡; }else{//从真正被删除的节点的父节点开始检查树的高度;(lr是真正被删除的节点);lr:target节点的左节点中最大值节点(叶子节点) target.data = lr.data; - parent = lr.father; + parent = lr.parent; deleteNode(lr,parent,null); } @@ -151,7 +153,7 @@ public class AVL { }else{ parent.right = val; } - if(val != null)val.father = parent; + if(val != null)val.parent = parent; } public Node searchNode(int val,Node node){ if(node == null)return null;//没找到; @@ -164,7 +166,7 @@ public class AVL { boolean updateHeight= updateHeight(node); if(!updateHeight || tree_rotate(node))return;//节点的高度没有更新,说明这个节点之上的树节点高度都不会受到影响,不用向上更新高度;同时添加新节点之前,tree保持平衡,因此不影响高度时,tree也会保持平衡; // if(tree_rotate(node))return;//调整一次之后,失衡的节点高度-1与添加节点导致高度 +1 抵消了;与添加前一样,因此不需要向上调整了; - insertBalance(node.father); + insertBalance(node.parent); } /** * 在删除调整时,调节一次之后;整棵树中仍然存在不平衡节点的可能; @@ -188,10 +190,10 @@ public class AVL { if(node == null)return ; boolean update = updateHeight(node); boolean rotate = tree_rotate(node); - if(!update && !rotate)return;//当node节点没有更新高度,左右子节点没有失衡;==》表示node节点时平衡的,删除的节点不会影响node之上的高度;因此不用向上递归 + if(!update && !rotate)return;//当node节点没有更新高度,并不能说明左右子节点没有失衡;==》有可能是删除了高度较低的分支,导致node节点的高度没有变;但这种情况可能会导致node失衡;只有当节点不做旋转且高度不变,这个时候就是平衡的 // if(rotate)node = node.father;//在树进行调整之后,原node会调整在树的下一层,(不管是四种中的哪一种,node都会下沉)因此为了继续向上调整,需要将调整后的顶点返回; // deleteBalance(node.father); - deleteBalance(node.father.father); + deleteBalance(node.parent.parent); } /* return :false====> 没有调整树的平衡 @@ -235,18 +237,18 @@ public class AVL { if(res > 0){ if(root.right != null)return insert(newNode,root.right); root.right = newNode; - newNode.father = root; + newNode.parent = root; }else{ if(root.left != null)return insert(newNode,root.left); root.left = newNode; - newNode.father = root; + newNode.parent = root; } return true; } void printNodeVal(List nodes){ List children = new ArrayList<>(); for(Node node : nodes ){ - Node f = node.father; + Node f = node.parent; Integer fd = f == null? null : f.data; System.out.print(node.data+","); if(node.left!=null)children.add(node.left); @@ -262,6 +264,7 @@ public class AVL { List nodes = new ArrayList<>(); nodes.add(root); printNodeVal(nodes); + } } diff --git a/balanceTree/src/main/java/BPlusTree.java b/balanceTree/src/main/java/BPlusTree.java index e58a8e1..220ee10 100644 --- a/balanceTree/src/main/java/BPlusTree.java +++ b/balanceTree/src/main/java/BPlusTree.java @@ -419,10 +419,7 @@ public class BPlusTree { System.out.print(node.keys[i]); else System.out.print(node.keys[i]+","); - - } - if(node.children == null){ System.out.print("}] <==> "); continue; diff --git a/balanceTree/src/main/java/BRT.java b/balanceTree/src/main/java/RBT.java similarity index 99% rename from balanceTree/src/main/java/BRT.java rename to balanceTree/src/main/java/RBT.java index a6d314c..7bc702f 100644 --- a/balanceTree/src/main/java/BRT.java +++ b/balanceTree/src/main/java/RBT.java @@ -5,7 +5,7 @@ import java.util.List; * @author myd * @date 2022/5/11 21:54 */ -public class BRT {//RED_BLACK Tree +public class RBT {//RED_BLACK Tree Node root; class Node{ Node parent; @@ -58,7 +58,7 @@ public class BRT {//RED_BLACK Tree * 颜色调整 * @param node */ - private void addBalance(Node node){ + void addBalance(Node node){ if(!(isRed(node) && isRed(node.parent)))return;//父节点为黑色。不会产生冲突; // //一定存在祖父节点:原因: node[red] -> parent[red],如果parent是root节点那就违反红黑树原则,因此parent必定存在一个父节点 // //并且grandpa节点的颜色一定是黑色的;如果是红色也会违反红黑树的规定; diff --git a/balanceTree/src/test/java/RBTTest.java b/balanceTree/src/test/java/RBTTest.java index a04163e..b094b20 100644 --- a/balanceTree/src/test/java/RBTTest.java +++ b/balanceTree/src/test/java/RBTTest.java @@ -17,7 +17,7 @@ public class RBTTest { */ @Test public void testADD(){ - BRT brt = new BRT(); + RBT brt = new RBT(); for (int i = 0; i <10 ; i++) { brt.addVal(i); } @@ -30,7 +30,7 @@ public class RBTTest { */ @Test public void testDELETE(){ - BRT brt = new BRT(); + RBT brt = new RBT(); for (int i = 0; i <10 ; i++) { brt.addVal(i); } -- Gitee From fc1d53fd00e6c46ed6f1b953bc69873876e6537a Mon Sep 17 00:00:00 2001 From: myd <815777051@qq.com> Date: Sun, 9 Oct 2022 21:50:08 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- balanceTree/src/main/java/R20220707/RBT.java | 94 ++++++++-- balanceTree/src/main/java/treePrint/Node.java | 30 +++ .../src/main/java/treePrint/TreePrint.java | 172 ++++++++++++++++++ 3 files changed, 280 insertions(+), 16 deletions(-) create mode 100644 balanceTree/src/main/java/treePrint/Node.java create mode 100644 balanceTree/src/main/java/treePrint/TreePrint.java diff --git a/balanceTree/src/main/java/R20220707/RBT.java b/balanceTree/src/main/java/R20220707/RBT.java index 08f0070..a57ecf3 100644 --- a/balanceTree/src/main/java/R20220707/RBT.java +++ b/balanceTree/src/main/java/R20220707/RBT.java @@ -1,6 +1,8 @@ package R20220707; import org.junit.Test; +import treePrint.Node; +import treePrint.TreePrint; import java.util.*; @@ -13,16 +15,16 @@ public class RBT { Node root; - class Node{ - Node parent; - Node left; - Node right; - boolean red = true;//新节点都是红色; - int data; - public Node(int val){ - data = val; - } - } +// class Node{ +// Node parent; +// Node left; +// Node right; +// boolean red = true;//新节点都是红色; +// int data; +// public Node(int val){ +// data = val; +// } +// } Node LL_rotate(Node node){ Node parent = node.parent; @@ -325,28 +327,52 @@ public class RBT { void init(){ if(root == null)return; midOrder(root); + int offset=0; + System.out.println("=====================计算坐标======================"); for (int i = 0; i < mid.size(); i++) { - map.put(mid.get(i),i); + + map.put(mid.get(i),i+offset); + + if(i %6!=0) + System.out.print("("+mid.get(i).data+",x="+(i+offset)+",offset="+offset+")"+"\t"); + else + System.out.print("\n"+"("+mid.get(i).data+",x="+(i+offset)+",offset="+offset+")"+"\t"); + + + offset+=numberLength(mid.get(i)); } + System.out.println("\n\n================================================\n"); } + int numberLength(Node node){ + if(node == null)return 0; + int value = node.data; + int count=1; + while((value/=10)>0){ + count++; + } + return count/4; + } + void printLevel(List nodes){ String VLine = ""; String dataLine = ""; String line = ""; int lastNodeIndex = 0; int lastRightIndex = 0; + Node lastNode = null; for (Node node : nodes) { int x = map.get(node); String addEmpty = getEmpty(x-lastNodeIndex); - lastNodeIndex = x; - VLine += addEmpty+"|";//竖线拼接 + + VLine += addEmpty+"|";//竖线拼接 //数字拼接 + String numberEmpty = getEmpty(x-lastNodeIndex-numberLength(lastNode)); if(node.red) - dataLine+= addEmpty +"\033[91;1m"+node.data+"\033[0m";//打印红色 + dataLine+= numberEmpty +"\033[91;1m"+node.data+"\033[0m";//打印红色 else - dataLine += addEmpty+node.data; + dataLine += numberEmpty+node.data; Node left = node.left; Node right = node.right; @@ -369,6 +395,8 @@ public class RBT { String difEmpty = getEmpty(dif); line += difEmpty + curLine;//拼接线段 lastRightIndex = rightIndex == -1 ? x : rightIndex; + lastNode = node; + lastNodeIndex = x; } System.out.println(VLine +"\n" + dataLine +"\n" + line); } @@ -432,9 +460,20 @@ public class RBT { @Test public void test(){ - for (int i = 0; i < 31; i++) { + for (int i = 1052; i < 1240; i+=50) { addVal(i); } + addVal(1);//占0个\t + addVal(10); + addVal(100); + addVal(1000);//占1个\t + addVal(10000); + addVal(1000000); + addVal(10000000);//占2个\t +// addVal(10000001); +// addVal(10000003); +// addVal(10000004); +// addVal(10000005); System.out.println("\n+++++++++++++++++++++++++++++++++++++++TreePrint test++++++++++++++++++++++++++++++++++++++"); @@ -445,6 +484,29 @@ public class RBT { System.out.println("[end] print tree time:"+(end-start)+"ms"); + + + } + @Test + public void test8(){ + for (int i = 1052; i < 1240; i+=50) { + addVal(i); + } + addVal(1);//占0个\t + addVal(10); + addVal(100); + addVal(1000);//占1个\t + addVal(10000); + addVal(1000000); + addVal(10000000);//占2个\t + + //自己构建的二叉树 的node节点使用treePrint.Node就可以直接使用TreePrint类用来打印 + + + //将二叉树的root节点传入到TreePrint中,构建打印对象; + TreePrint treePrint = new TreePrint(root); + treePrint.print(); + } diff --git a/balanceTree/src/main/java/treePrint/Node.java b/balanceTree/src/main/java/treePrint/Node.java new file mode 100644 index 0000000..15031b9 --- /dev/null +++ b/balanceTree/src/main/java/treePrint/Node.java @@ -0,0 +1,30 @@ +package treePrint; + +/** + * @author myd + * @date 2022/10/9 17:11 + */ + +public class Node { + + public Node parent; + public Node left; + public Node right; + public int data; + public boolean red=true; + public Node(Node parent,Node left,Node right ,int data){ + this.data = data; + this.parent = parent; + this.left = left; + this.right = right; + } + + public Node(int data){ + this(null,null,null,data); + } + + public Node(Node parent,int data){ + this(parent,null,null,data); + } + + } diff --git a/balanceTree/src/main/java/treePrint/TreePrint.java b/balanceTree/src/main/java/treePrint/TreePrint.java new file mode 100644 index 0000000..29d5312 --- /dev/null +++ b/balanceTree/src/main/java/treePrint/TreePrint.java @@ -0,0 +1,172 @@ +package treePrint; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author myd + * @date 2022/10/7 12:47 + */ + +public class TreePrint { + Node root; + public TreePrint(Node root){ + this.root = root; + } + + private static final String BASE_EMPTY_LINK = "\t"; + + private static final String BASE_LINE_LINK = "____"; + + private static final String V_LINE = "|"; + + private Map nodesCoo = new HashMap<>(); + + class CooAndLen{ + private int x;//x坐标 + private int length;//数字长度 + + public CooAndLen(int x,int length){ + this.x = x; + this.length = length; + } + } + + void calculateCoordinate(){ + List nodes = new ArrayList<>(); + midOrder(root,nodes); + if(nodes.isEmpty())return; + int offset = 0; + for (int i = 0; i < nodes.size(); i++) { + Node node = nodes.get(i); + int len = numberLength(node); + nodesCoo.put(node,new CooAndLen(i+offset,len)); + offset+=len; + } + } + + void midOrder(Node cur,List list){ + if(cur == null)return; + midOrder(cur.left,list); + list.add(cur); + midOrder(cur.right,list); + } + + int numberLength(Node node){ + if(node == null)return 0; + int count=1,data = node.data; + while((data/=10) >0){ + count++; + } + return count/=4; + } + + public void print(){ + calculateCoordinate(); + List nodes = new ArrayList<>(); + nodes.add(root); + printRow(nodes); + } + + + void printRow(List nodes){ + if(nodes.size()==0)return; + List children = new ArrayList<>(nodes.size()*2); + String VLineInNumHead = ""; + String dataLine = ""; + String linkSonLine=""; + Node prev=null; + Node lastRight=null; + for (Node node : nodes) { + String VLineEmpty = getLinkLine(nodeDistance(node,prev,0),BASE_EMPTY_LINK); + String numberEmpty = getLinkLine(nodeDistance(node,prev,prevLength(prev)),BASE_EMPTY_LINK); + VLineInNumHead+=VLineEmpty+V_LINE; + if(node.red) + dataLine += numberEmpty + "\033[91;1m" + node.data + "\033[0m"; + else + dataLine += numberEmpty + node.data; + if(node.left == null && node.right == null){ + prev = node; + continue; + } + String linkSon = linkSonLine(node,children); + String sonLineEmpty = getLinkLine(nodeDistance(leftNode(node),lastRight,0),BASE_EMPTY_LINK); + linkSonLine += sonLineEmpty + linkSon; + prev = node; + lastRight=lastRight(prev); + } + System.out.println(VLineInNumHead +"\n"+dataLine +"\n"+linkSonLine); + printRow(children); + } + + String linkSonLine(Node cur,List children){ + Node left = cur.left; + Node right = cur.right; + String leftLinkSonLine =""; + String rightLinkSonLine=""; + if(left != null){ + children.add(left); + leftLinkSonLine=getLinkLine(nodeDistance(cur,left,0),BASE_LINE_LINK); + } + if(right != null){ + children.add(right); + rightLinkSonLine=getLinkLine(nodeDistance(right,cur,0),BASE_LINE_LINK); + } + return leftLinkSonLine + V_LINE + rightLinkSonLine; + + } + + int prevLength(Node node){ + return node == null ? 0: nodesCoo.get(node).length; + } + + Node lastRight(Node prev){ + if(prev == null) + return null; + else + return prev.right == null ? prev:prev.right; + } + + Node leftNode(Node node){ + return node.left != null ? node.left : node; + } + + + + + int nodeIndex(Node node){ + return node == null ? 0 : nodesCoo.get(node).x; + } + + int nodeDistance(Node cur,Node prev,int prevNumLen){ + return nodeIndex(cur) - nodeIndex(prev)-prevNumLen; + } + + + String getLinkLine(int dis,String linkStr){ + String str=""; + for (int i = 0; i Date: Sun, 9 Oct 2022 21:56:01 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=9E=84=E5=BB=BA=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- balanceTree/src/main/java/treePrint/TreePrint.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/balanceTree/src/main/java/treePrint/TreePrint.java b/balanceTree/src/main/java/treePrint/TreePrint.java index 29d5312..7f342e0 100644 --- a/balanceTree/src/main/java/treePrint/TreePrint.java +++ b/balanceTree/src/main/java/treePrint/TreePrint.java @@ -60,7 +60,7 @@ public class TreePrint { while((data/=10) >0){ count++; } - return count/=4; + return count/4; } public void print(){ -- Gitee