From 87b8ad69b6469747a06c83ea0d195f34206137f7 Mon Sep 17 00:00:00 2001 From: Patrick Date: Tue, 23 May 2017 00:16:56 +0800 Subject: [PATCH] =?UTF-8?q?tree=E7=BB=83=E4=B9=A0=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../basic/tree/BinarySearchTree.java | 205 ++++++++++++++++++ .../basic/tree/BinarySearchTreeTest.java | 77 +++++++ .../coding2017/basic/tree/BinaryTreeNode.java | 6 +- 3 files changed, 285 insertions(+), 3 deletions(-) create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinarySearchTree.java create mode 100644 group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinarySearchTreeTest.java diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinarySearchTree.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinarySearchTree.java new file mode 100644 index 0000000000..175711100b --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinarySearchTree.java @@ -0,0 +1,205 @@ +package com.github.ipk2015.coding2017.basic.tree; + +import java.util.ArrayList; +import java.util.List; + +public class BinarySearchTree { + + BinaryTreeNode root; + public BinarySearchTree(BinaryTreeNode root){ + this.root = root; + } + public BinaryTreeNode getRoot(){ + return root; + } + public T findMin(){ + T min = findMinInOneNode(root,root.getData()); + return min; + } + + private T findMinInOneNode(BinaryTreeNode node,T result){ + BinaryTreeNode rightNode = node.getRight(); + if(null != rightNode){ + T right = findMinInOneNode(rightNode,result); + result = compareMin(right,result); + } + + BinaryTreeNode leftNode = node.getLeft(); + if(null != leftNode){ + T left = findMinInOneNode(leftNode,result); + result = compareMin(left,result); + }else{ + result = compareMin(node.getData(),result); + } + return result; + } + private T compareMin(T data,T min){ + int compareTo = min.compareTo(data); + return compareTo > 0 ? data : min; + } + public T findMax(){ + T result = findMaxInOneNode(root,root.getData()); + return result; + } + private T findMaxInOneNode(BinaryTreeNode node,T result){ + BinaryTreeNode leftNode = node.getLeft(); + if(null != leftNode){ + T left = findMaxInOneNode(leftNode,result); + result = compareMax(left,result); + } + + BinaryTreeNode rightNode = node.getRight(); + if(null != rightNode){ + T right = findMaxInOneNode(rightNode,result); + result = compareMax(right,result); + }else{ + result = compareMax(node.getData(),result); + } + return result; + } + private T compareMax(T data,T min){ + int compareTo = min.compareTo(data); + return compareTo < 0 ? data : min; + } + + public int height() { + return findHeightInOneNode(root); + } + + private int findHeightInOneNode(BinaryTreeNode node){ + BinaryTreeNode left = node.getLeft(); + BinaryTreeNode right = node.getRight(); + if(null == left && null == right){ + return 1; + } + int leftHeight = 0; + if(null != left){ + leftHeight = findHeightInOneNode(left); + } + + int rightHeight = 0; + if(null != right){ + rightHeight = findHeightInOneNode(right); + } + + return leftHeight > rightHeight ? leftHeight+1: rightHeight+1; + } + + public int size() { + List list = BinaryTreeUtil.inOrderVisit(root); + return list.size(); + } + /* + * 首先我们找到待删除的节点Z,如果节点Z的两个孩子均为空,那么将其父节点中对应指向Z的指针置为空,然后删除节点Z。 + * 如果节点Z仅有一个孩子,那么将Z节点的父节点中指向Z的指针指向Z仅有的孩子,然后删除节点Z。 + * 如果节点Z有两个非空的子节点,那么找到节点Z的中序后继节点Y(即右子树的最左节点),将节点Y的Key值覆盖节点Z的Key值, + * 此时节点Y的两个孩子均为空或者只有一个右孩子,将节点Y的右指针里的值覆盖其父节点中指向Y的指针,然后删除节点Y。 + * 注意:不可按节点数据是按左小右大来查找,因为删除后会发生错乱。 + * */ + public void remove(T e){ + List> list; + boolean isRoot = e.compareTo(root.getData()) == 0; + if(isRoot){ + BinaryTreeNode virtualNode = new BinaryTreeNode(); + virtualNode.right = root; + list = new ArrayList>(); + list.add(virtualNode); + list.add(root); + }else{ + list = findOneNodeAndParentNode(e); + } + if(list.isEmpty()){ + return; + } + BinaryTreeNode parentNode = list.get(0); + BinaryTreeNode rmNode = list.get(1); + + boolean isLeft = null != parentNode.getLeft() && rmNode.getData().compareTo(parentNode.getLeft().getData()) == 0; + BinaryTreeNode leftNode = rmNode.getLeft(); + BinaryTreeNode rightNode = rmNode.getRight(); + if(null == leftNode && null == rightNode){ + if(isLeft){ + parentNode.left = null; + }else{ + parentNode.right = null; + } + }else if(null == leftNode && null != rightNode){ + if(isLeft){ + parentNode.left = rightNode; + }else{ + parentNode.right = rightNode; + } + rmNode.right = null; + }else if(null == rightNode && null != leftNode){ + if(isLeft){ + parentNode.left = leftNode; + }else{ + parentNode.right = leftNode; + } + rmNode.left = null; + }else if(null != rightNode && null != leftNode){ + BinaryTreeNode leftParentInOrder = rightNode; + BinaryTreeNode leftNodeInOrder = leftParentInOrder.getLeft(); + if(null == leftNodeInOrder){ + rmNode.data = rightNode.getData(); + rmNode.right = rightNode.getRight(); + rightNode.right = null; + }else{ + while(null != leftNodeInOrder.getLeft()){ + leftParentInOrder = leftNodeInOrder; + leftNodeInOrder = leftParentInOrder.getLeft(); + } + rmNode.data = leftNodeInOrder.getData(); + leftParentInOrder.left = leftNodeInOrder.right; + leftNodeInOrder.right = null; + } + } + if(isRoot){ + BinaryTreeNode virtualParent = list.get(0); + root = virtualParent.right; + virtualParent.right = null; + } + + } + + private List> findOneNodeAndParentNode(T e){ + List> list = new ArrayList>(); + + findNodeAParentByData(list,root,e); + + return list; + } + + private boolean findNodeAParentByData(List> list,BinaryTreeNode node,T e){ + BinaryTreeNode leftNode = node.getLeft(); + if(null !=leftNode){ + if(e.compareTo(leftNode.getData()) == 0){ + list.add(node); + list.add(leftNode); + return true; + }else{ + boolean isFind1 = findNodeAParentByData(list,leftNode,e); + if(isFind1){ + return true; + } + } + } + + BinaryTreeNode rightNode = node.getRight(); + if(null !=rightNode){ + if(e.compareTo(rightNode.getData()) == 0){ + list.add(node); + list.add(rightNode); + return true; + }else{ + boolean isFind2 = findNodeAParentByData(list,rightNode,e); + if(isFind2){ + return true; + } + } + } + return false; + } + +} + diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinarySearchTreeTest.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinarySearchTreeTest.java new file mode 100644 index 0000000000..42d3b6c721 --- /dev/null +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinarySearchTreeTest.java @@ -0,0 +1,77 @@ +package com.github.ipk2015.coding2017.basic.tree; + + + +import static org.junit.Assert.fail; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + + + +public class BinarySearchTreeTest { + + BinarySearchTree tree = null; + + @Before + public void setUp() throws Exception { + BinaryTreeNode root = new BinaryTreeNode(6); + root.left = new BinaryTreeNode(2); + root.right = new BinaryTreeNode(8); + root.left.left = new BinaryTreeNode(1); + root.left.right = new BinaryTreeNode(4); + root.left.right.left = new BinaryTreeNode(3); + tree = new BinarySearchTree(root); + } + + @After + public void tearDown() throws Exception { + tree = null; + } + + @Test + public void testFindMin() { + Assert.assertEquals(1, tree.findMin().intValue()); + + } + + @Test + public void testFindMax() { + Assert.assertEquals(8, tree.findMax().intValue()); + } + + @Test + public void testHeight() { + Assert.assertEquals(4, tree.height()); + } + + @Test + public void testSize() { + Assert.assertEquals(6, tree.size()); + } + + @Test + public void testRemoveLeaf() { + tree.remove(4); + BinaryTreeNode root= tree.getRoot(); + Assert.assertEquals(3, root.left.right.data.intValue()); + + } + @Test + public void testRemoveMiddleNode() { + tree.remove(2); + BinaryTreeNode root= tree.getRoot(); + Assert.assertEquals(3, root.left.data.intValue()); + Assert.assertEquals(4, root.left.right.data.intValue()); + } + @Test + public void testRemoveRootNode() { + tree.remove(6); + BinaryTreeNode root= tree.getRoot(); + Assert.assertEquals(8, root.data.intValue()); + Assert.assertEquals(2, root.left.data.intValue()); + + } +} diff --git a/group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinaryTreeNode.java b/group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinaryTreeNode.java index 7da18fa204..3ac7bcb965 100644 --- a/group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinaryTreeNode.java +++ b/group24/121111914/src/com/github/ipk2015/coding2017/basic/tree/BinaryTreeNode.java @@ -4,9 +4,9 @@ public class BinaryTreeNode { - private T data; - private BinaryTreeNode left; - private BinaryTreeNode right; + public T data; + public BinaryTreeNode left; + public BinaryTreeNode right; public BinaryTreeNode(T data){ this.data=data;