二叉树(一)
二叉树,结合了两种数据结构的优点:一种是有序数组,一种是链表。在树中查找数据项的速度和在有序数组查找一样快;并且插入和删除数据项的速度和链表一样快。
1)在有序数组插入数据太慢:通过二分查找找到该位置,但每次所有比新数据大的坐标都要往后移动一位。不适合于频繁插入和删除数据的操作。
2)在链表查找太慢:每次查找都必须从表头开始查找,即便是有序链表也是一样。(当然有序链表通过指定值找到该链接点的速度比无序链表快一些)
树的术语:
1)路径:顺着节点的边从一个节点走到另一个节点,所经过的节点顺序排列就称为“路径”。
2)根:一棵树只有一个根,最顶端的位置,而且从根到每个节点的路径仅有一条。
3)父节点:每个节点(除了根)都有一条向上连接到另一个节点,那么上面的节点就称为“父节点”。
4)子节点:每个节点都有一条或多条向下连接到其它的节点,那么下面的节点就称为“子节点”。
5)叶节点:没有子节点的节点就称为“叶节点”。
6)子树:每个节点都可以是子树的根,它和它所有的子节点、子节点的子节点都含在子树中。一个节点的子树包含它所有的子孙。
7)访问:当程序流程到达某个节点,并进行相应的操作。就称“访问”这个节点。
8)层:一个节点的层数是从根开始到这个节点有多少代,假设根是0层,那么它的子节点是1层,再下一节点是2层。。。
9)关键字:对象中有一个数据域被指定为关键字,这个值常用来查询或其它操作。
10)二叉树:如果树中每个节点最多只有两个子节点,这样的树被称为“二叉树”。最简单也最常用的。
11)二叉搜索树:一个节点的左子节点的关键字是小于这个节点,右子结点的关键字是大于或等于这个父节点。
12)后继:在被删除的节点有两个子节点的情况下,需要拿在中序遍历中,被删的节点的下一个访问的节点替换,该替换的节点叫做被删节点的中序后继,简称后继。
1 public class Node { 2 3 private Node leftChild; 4 5 private Node rightChild; 6 7 private int iData; 8 9 private double dData; 10 11 public Node(int i, double d) { 12 iData = i; 13 dData = d; 14 } 15 16 public int getiData() { 17 return iData; 18 } 19 20 public double getdData() { 21 return dData; 22 } 23 24 public Node getLeftChild() { 25 return leftChild; 26 } 27 28 public void setLeftChild(Node leftChild) { 29 this.leftChild = leftChild; 30 } 31 32 public Node getRightChild() { 33 return rightChild; 34 } 35 36 public void setRightChild(Node rightChild) { 37 this.rightChild = rightChild; 38 } 39 40 public void displayNode() { 41 System.out.println("{ " + iData + " , " + dData + " }"); 42 } 43 44 }
1 public class Tree { 2 3 private Node root; 4 5 public boolean isEmpty() { 6 return root == null; 7 } 8 9 public void insert(int i, double d) { 10 Node node = new Node(i, d); 11 if (isEmpty()) { 12 root = node; 13 } 14 else { 15 Node current = root; 16 Node parent = null; 17 while (current != null) { 18 parent = current; 19 if (i < current.getiData()) { 20 current = current.getLeftChild(); 21 } 22 else { 23 current = current.getRightChild(); 24 } 25 } 26 if (i < parent.getiData()) { 27 parent.setLeftChild(node); 28 } 29 else { 30 parent.setRightChild(node); 31 } 32 } 33 } 34 35 public Node find(int key) { 36 Node current = root; 37 while (current != null) { 38 if (key == current.getiData()) { 39 return current; 40 } 41 else if (key < current.getiData()) { 42 current = current.getLeftChild(); 43 } 44 else { 45 current = current.getRightChild(); 46 } 47 } 48 return null; 49 } 50 51 private void inOrder(Node localRoot) { 52 if (localRoot != null) { 53 inOrder(localRoot.getLeftChild()); 54 System.out.print("Local Node : "); 55 localRoot.displayNode(); 56 inOrder(localRoot.getRightChild()); 57 } 58 } 59 60 private void preOrder(Node localRoot) { 61 if (localRoot != null) { 62 System.out.print("Local Node : "); 63 localRoot.displayNode(); 64 preOrder(localRoot.getLeftChild()); 65 preOrder(localRoot.getRightChild()); 66 } 67 } 68 69 private void postOrder(Node localRoot) { 70 if (localRoot != null) { 71 postOrder(localRoot.getLeftChild()); 72 postOrder(localRoot.getRightChild()); 73 System.out.print("Local Node : "); 74 localRoot.displayNode(); 75 } 76 } 77 78 //中序遍历 79 public void inOrder() { 80 inOrder(root); 81 } 82 83 //前序遍历 84 public void preOrder() { 85 preOrder(root); 86 } 87 88 //后序遍历 89 public void postOrder() { 90 postOrder(root); 91 } 92 93 public Node minNode() { 94 Node current = root; 95 Node parent = null; 96 while (current != null) { 97 parent = current; 98 current = current.getLeftChild(); 99 } 100 return parent; 101 } 102 103 public Node maxNode() { 104 Node current = root; 105 Node parent = null; 106 while (current != null) { 107 parent = current; 108 current = current.getRightChild(); 109 } 110 return parent; 111 } 112 113 /* 114 * 删除节点需要考虑3种情况 115 * 1、该节点没有子节点 116 * 2、该节点只有一个子节点(用子节点替换被删掉的节点) 117 * 3、该节点有两个子节点 118 */ 119 public Node delete(int key) { 120 Node current = root; 121 Node parent = null; 122 123 while (current != null) { 124 if (key == current.getiData()) { 125 break; 126 } 127 else if (key < current.getiData()) { 128 parent = current; 129 current = current.getLeftChild(); 130 } 131 else { 132 parent = current; 133 current = current.getRightChild(); 134 } 135 } 136 if (current == null) { 137 return null; 138 } 139 //1、该节点没有子节点 140 if (current.getLeftChild() == null && current.getRightChild() == null) { 141 //判断是否根节点 142 if (current == root) { 143 root = null; 144 } 145 else { 146 if (key < parent.getiData()) { 147 parent.setLeftChild(null); 148 } 149 else { 150 parent.setRightChild(null); 151 } 152 } 153 } 154 //2、该节点只有一个子节点 155 else if (current.getLeftChild() == null) { 156 if (current == root) { 157 root = null; 158 } 159 else { 160 if (key < parent.getiData()) { 161 parent.setLeftChild(current.getRightChild()); 162 } 163 else { 164 parent.setRightChild(current.getRightChild()); 165 } 166 } 167 } 168 else if (current.getRightChild() == null) { 169 if (current == root) { 170 root = null; 171 } 172 else { 173 if (key < parent.getiData()) { 174 parent.setLeftChild(current.getLeftChild()); 175 } 176 else { 177 parent.setRightChild(current.getLeftChild()); 178 } 179 } 180 } 181 //3、该节点有两个子节点 182 else { 183 Node successor = getSuccessor(current); 184 if (current == root) { 185 root = successor; 186 } 187 else { 188 if (key < parent.getiData()) { 189 parent.setLeftChild(successor); 190 } 191 else { 192 parent.setRightChild(successor); 193 } 194 } 195 successor.setLeftChild(current.getLeftChild()); 196 } 197 return current; 198 199 } 200 201 private Node getSuccessor(Node delNode) { 202 Node successorParent = delNode; 203 Node successor = delNode; 204 Node current = delNode.getRightChild(); 205 while (current != null) { 206 successorParent = successor; 207 successor = current; 208 current = current.getLeftChild(); 209 } 210 if (successor != delNode.getRightChild()) { 211 successorParent.setLeftChild(successor.getRightChild()); 212 successor.setRightChild(delNode.getRightChild()); 213 } 214 return successor; 215 } 216 217 }
1 public static void main(String[] args) { 2 Tree tree = new Tree(); 3 tree.insert(50, 1.5); 4 tree.insert(25, 1.6); 5 tree.insert(75, 1.7); 6 tree.insert(12, 1.8); 7 tree.insert(37, 1.9); 8 tree.insert(43, 2.0); 9 tree.insert(30, 2.1); 10 tree.insert(33, 2.2); 11 tree.insert(87, 2.3); 12 tree.insert(77, 2.4); 13 tree.insert(78, 2.5); 14 tree.insert(74, 2.5); 15 tree.insert(90, 2.6); 16 tree.insert(102, 2.7); 17 tree.insert(107, 2.8); 18 tree.insert(101, 2.9); 19 tree.inOrder(); 20 System.out.println("---------------------------"); 21 tree.delete(12); 22 tree.delete(30); 23 tree.delete(87); 24 tree.inOrder(); 25 }
打印结果:
Local Node : { 12 , 1.8 }
Local Node : { 25 , 1.6 }
Local Node : { 30 , 2.1 }
Local Node : { 33 , 2.2 }
Local Node : { 37 , 1.9 }
Local Node : { 43 , 2.0 }
Local Node : { 50 , 1.5 }
Local Node : { 74 , 2.5 }
Local Node : { 75 , 1.7 }
Local Node : { 77 , 2.4 }
Local Node : { 78 , 2.5 }
Local Node : { 87 , 2.3 }
Local Node : { 90 , 2.6 }
Local Node : { 101 , 2.9 }
Local Node : { 102 , 2.7 }
Local Node : { 107 , 2.8 }
---------------------------
Local Node : { 25 , 1.6 }
Local Node : { 33 , 2.2 }
Local Node : { 37 , 1.9 }
Local Node : { 43 , 2.0 }
Local Node : { 50 , 1.5 }
Local Node : { 74 , 2.5 }
Local Node : { 75 , 1.7 }
Local Node : { 77 , 2.4 }
Local Node : { 78 , 2.5 }
Local Node : { 90 , 2.6 }
Local Node : { 101 , 2.9 }
Local Node : { 102 , 2.7 }
Local Node : { 107 , 2.8 }