查找二叉树的定义

查找二叉树 算法 第1张

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

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

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

二叉树的后继节点

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

查找二叉树 算法 第2张

①如果节点有右子树,则该节点的后继节点就是往右子树出发,然后转到右子树的左子树,一直到左子树的左子树为空(即输入节点的右子树的最左子树,例如节点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 }

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄