zoukankan      html  css  js  c++  java
  • 查找二叉树

    查找二叉树的定义

     一棵二叉搜索树(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 }
  • 相关阅读:
    Atitit.php  nginx页面空白 并返回500的解决
    Atitit.php  nginx页面空白 并返回500的解决
    Atitit .linux 取回root 密码q99
    Atitit .linux 取回root 密码q99
    atitit.农历的公式与原理以及农历日期运算
    atitit.农历的公式与原理以及农历日期运算
    Atitit.用户权限服务 登录退出功能
    Atitit.用户权限服务 登录退出功能
    atitit.atiOrm.js v2 q61 版本新特性.docx
    Atitit.报名模块的管理
  • 原文地址:https://www.cnblogs.com/xiaozhongfeixiang/p/11700479.html
Copyright © 2011-2022 走看看