查找二叉树

查找二叉树的定义

 

 一棵二叉搜索树(Binary Sort Tree)是以一棵二叉树来组织的,可以用链表数据结构来表示,其中,每一个结点就是一个对象,一般地,包含数据值和指向孩子(也可能是父母)的指针。如果某个孩子结点不存在,其指针为空(NULL)。

  • 查找树的左右子树各是一棵查找树
  • 若查找树的左子树非空,则其左子树上的各节点值均小于根节点的值。
  • 若查找树的右子树非空,则其右子树上的各节点值均大于根节点的值。

二叉树的后继节点

对于下面的二叉树,8的后继节点为9(题目说的中序遍历),6的后继节点为7,5的后继节点为6

①如果节点有右子树,则该节点的后继节点就是往右子树出发,然后转到右子树的左子树,一直到左子树的左子树为空(即输入节点的右子树的最左子树,例如节点8,后继节点就是9)其实就是找,结点的右结点里值最小结点。

②如果节点没有右子树,则向上寻找父节点,直到父节点的左子树等于当前节点,则该父节点就是后继节点(如节点7,没有右子树,则向上找,这时到6这个节点,因为6的左子树不等于7,所以继续向上找,这时到节点8,8的左子树等于当前节点6,所以返回8)

 查找二叉树代码实现

  1 package cn.itcast.test;
  2 
  3 import sun.reflect.generics.tree.Tree;
  4 
  5 public class SearchBinaryTree {
  6     public static void main(String[] args) {
  7         SearchBinaryTree binaryTree = new SearchBinaryTree();
  8         int[] intArray = new int[]{50, 30, 20, 44, 88, 33, 87, 16, 7, 77};
  9         for (int i : intArray) {
 10             TreeNode put = binaryTree.put(i);
 11         }
 12         binaryTree.midOrder(binaryTree.root);
 13         System.out.println("-----");
 14         try {
 15             binaryTree.deleteNode(44);
 16             binaryTree.midOrder(binaryTree.root);
 17         } catch (Exception e) {
 18             e.printStackTrace();
 19         }
 20     }
 21 
 22     //定义根结点
 23     private TreeNode root;
 24 
 25     public SearchBinaryTree() {
 26 
 27     }
 28 
 29     /**
 30      * 中序遍历
 31      * @param node
 32      */
 33     public void midOrder(TreeNode node) {
 34         if (node == null) {
 35             return;
 36         } else {
 37             midOrder(node.leftChild);
 38             System.out.println(node.data);
 39             midOrder(node.rightChild);
 40         }
 41     }
 42 
 43     /**
 44      * 创建查找二叉树,添加结点
 45      */
 46     public TreeNode put(int data) {
 47         TreeNode node = null;//定义一个结点
 48         TreeNode parent = null;//定义一个父节点
 49         node = new TreeNode(0, data);//创建一个结点
 50         if (root == null) {
 51             root = node;//创建根节点
 52             return node;
 53         }
 54         node = root;
 55         while (node != null) {//找左右结点,直到note=null,跳出循环
 56             parent = node;//先暂时把当前结点当做父节点
 57             if (data > node.data) {//data:根节点
 58                 node = node.rightChild;
 59             } else if (data < node.data) {
 60                 node = node.leftChild;
 61             } else {
 62                 return node;
 63             }
 64         }
 65 
 66         //表示将此结点添加到相应位置
 67         node = new TreeNode(0, data);
 68         if (data < parent.data) {//传data值
 69             parent.leftChild = node;
 70             node.parent = parent;
 71         } else {
 72             parent.rightChild = node;
 73             node.parent = parent;
 74         }
 75         return node;
 76     }
 77 
 78 
 79     public void deleteNode(int key) throws Exception {
 80         //查找node结点
 81         TreeNode node = searchNode(key);
 82         if (node == null) {
 83             throw new Exception("该节点无法找到");
 84         } else {
 85             //删除该结点
 86             delete(node);
 87         }
 88     }
 89 
 90     private void delete(TreeNode node) throws Exception {
 91         //严谨,再判断一次,可以单独写一个方法判断
 92         if (node == null) {
 93             throw new Exception("该节点无法找到");
 94         } else {
 95             TreeNode parent = node.parent;
 96             //1.被删除的结点无左右孩子
 97             if (node.leftChild == null && node.rightChild == null) {
 98                 if (parent.leftChild == node) {
 99                     parent.leftChild = null;//断开父结点与其的连接,等于删除了
100                 } else {
101                     parent.rightChild = null;
102                 }
103                 return;
104             }
105             //2.被删除的结点有左无右
106             if (node.leftChild != null && node.rightChild == null) {
107                 if (parent.leftChild == node) {
108                     //在父结点的左边,并且有左无右
109                     parent.leftChild = node.leftChild;
110                 } else {
111                     //在父结点的右边,并且有左无右
112                     parent.rightChild = node.leftChild;
113                 }
114                 return;
115             }
116             //3.被删除的结点有右无左
117             if (node.leftChild == null && node.rightChild != null) {
118                 if (parent.leftChild == node) {
119                     //在父结点的左边,并且有右无左
120                     parent.leftChild = node.rightChild;
121                 } else {
122                     //在父结点的右边,并且有右无左
123                     parent.rightChild = node.rightChild;
124                 }
125                 return;
126             }
127             //4.被删除的结点有左有右
128             TreeNode next = getNextNode(node);//找到该结点node的后继结点
129             delete(next);//递归
130             node.data = next.data;//完成赋值
131         }
132     }
133 
134     /**
135      * 获取一个结点的后继结点
136      * @param node
137      * @return
138      */
139     private TreeNode getNextNode(TreeNode node) {
140         if (node == null) {
141             return null;
142         } else {
143             if (node.rightChild != null) {
144                 //找某结点的最小关键字结点
145                 return getMinTreeNode(node.rightChild);
146             } else {
147                 TreeNode parent = node.parent;
148                 //直到node是父结点的左结点,而不是父结点的右结点
149                 while (parent != null && node == parent.rightChild) {
150                     node = parent;
151                     parent = parent.parent;
152                 }
153                 return parent;
154             }
155         }
156     }
157 
158     private TreeNode getMinTreeNode(TreeNode node) {
159         if (node == null) {
160             return null;
161         } else {
162             //一直往左子树找,直到找到为止
163             while (node.leftChild != null) {
164                 node = node.leftChild;
165             }
166         }
167         return node;
168     }
169 
170     /**
171      * 找node结点,要么为空,要么找到
172      *
173      * @param key
174      * @return
175      */
176     private TreeNode searchNode(int key) {
177         TreeNode node = root;//为了从根节点开始查找
178         if (node == null) {
179             return null;
180         } else {
181             while (node != null && key != node.data) {
182                 if (key < node.data) {
183                     node = node.leftChild;//左子树永远比右子树小
184                 } else {
185                     node = node.rightChild;
186                 }
187             }
188         }
189         return node;
190     }
191 
192 
193     class TreeNode {
194         private int key;
195         private TreeNode leftChild;
196         private TreeNode rightChild;
197         private TreeNode parent;
198         private int data;
199 
200         public TreeNode(int key, int data) {
201             //调用父类的构造方法,即Object类的无参构造方法
202             super();
203             this.key = key;
204             this.data = data;
205             this.leftChild = null;
206             this.rightChild = null;
207             this.parent = null;
208         }
209 
210         public int getKey() {
211             return key;
212         }
213 
214         public void setKey(int key) {
215             this.key = key;
216         }
217 
218         public TreeNode getLeftChild() {
219             return leftChild;
220         }
221 
222         public void setLeftChild(TreeNode leftChild) {
223             this.leftChild = leftChild;
224         }
225 
226         public TreeNode getRightChild() {
227             return rightChild;
228         }
229 
230         public void setRightChild(TreeNode rightChild) {
231             this.rightChild = rightChild;
232         }
233 
234         public TreeNode getParent() {
235             return parent;
236         }
237 
238         public void setParent(TreeNode parent) {
239             this.parent = parent;
240         }
241 
242         public int getData() {
243             return data;
244         }
245 
246         public void setData(int data) {
247             this.data = data;
248         }
249     }
250 }

 

posted @ 2019-10-24 17:28  小中配奇  阅读(485)  评论(0编辑  收藏  举报