zoukankan      html  css  js  c++  java
  • 彻底理清二叉排序树的插入、查找、删除

    二叉排序树的概述

      二叉排序树也被成为二叉查找树或者二叉搜索树。它或者是一棵空的二叉树。它具备以下性质。

      若它的左子树不空,则左子树上所有结点的值均小于根结点的值。

      若它的右子树不空,则右子树上所有结点的值均大于根结点的值。

      它的左右子树也都是二叉排序树。

    简述二叉排序树原理与实现

      二叉排序树的建立根基是二叉链表。

    //二叉树节点
    public class BinaryTreeNode {
        public  int data;
        public BinaryTreeNode left;
        public BinaryTreeNode right;
    }

      假设有这样一组数据{11,2,5,7,3,9,4,66,55},那么它将构造这样一棵树结构。

      

      如何对搜索二叉树插入节点,从而构建一颗二叉树?

      根据二叉树的定义,向二叉排序树中插入节点s的过程,用伪代码描述:

        若root是空树,则将节点s作为根结点输入;

        否则,若s.data<root.data,则把节点s插入在root的左子树中;

        否则把结点s插入到root的右子树中;

      //构建搜索二叉树
        public  BinaryTreeNode build(int [] array){
            BinaryTreeNode root =new BinaryTreeNode(array[0]);  
            for( int i = 1 ; i < array.length ; i ++){  
                insertBST(root, array[i]);    
            }
            return root;
        }
        public BinaryTreeNode insertBST(BinaryTreeNode node,int data){
            if(node == null){  
                node = new BinaryTreeNode(data);  
                return node;  
            }else{  
                if(data <= node.data)  
                    node.left =  insertBST(node.left, data);  
                else 
                    node.right = insertBST(node.right,data);  
                return node;  
            }  
        }

      查找二叉树的指定值。

        若root是空树,则查找失败。

        若k=root.data,则查找成功。

        若k<root.data,则查找二叉树的左子树。

        若k>root.data,则查找二叉树的右子树。

    //查找元素
        public BinaryTreeNode serachBST(BinaryTreeNode root,int target){
            if(null==root)
                return null;
            else if(root.getData()==target)
                return root;
            else if(root.getData()>target)
                return serachBST(root.getLeft(), target);
            else
                return serachBST(root.getRight(), target);
        }

      删除二叉树的指定值。删除元素其实并不难,重点是删除要元素以后依然要保持二叉搜索树,不能让它头脚分离变成森林。

      假设要删除结点为p(2),节点分为三种类型,p是叶子节点,p只有一个孩子,p有两个孩子。

      情况一:假设p是叶子节点,只需要把p设为null即可。

      情况二:假设p有一个孩子。假设它有左孩子,那么把p节点等于左孩子;假设它有右孩子,那么把p节点等于右孩子。

       情况三:假设p有两个孩子。

            查找p节点右子树的最左子树节点,也就是p节点的右子树的最小结点s,以及s的双亲节点par;

            将s的数据域替换被删除结点p的数据域;

            若节点p的右孩子无子树,则将s的右子树接到par的右子树上;否则,将s的右子树接到par的左字数上;

      图例原始图

      

      图例情况一:假设删除结点p为9,无孩子节点。

      

      图例情况二:假设删除节点p为3,有右孩子节点。

      

      图例情况三:假设删除节点p为5,有左右孩子。

      

        public BinaryTreeNode deleteBST(BinaryTreeNode root,int key){
            if(root==null){
                return null;
            }
            if(root.data==key){
                return deleteNode(root);
            }else if(root.data<key){
                root.right=deleteBST(root.right, key);
            }else{
                root.left=deleteBST(root.left, key);
            }
            return root;
        }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">删除元素</span>
    <span style="color: #0000ff;">public</span><span style="color: #000000;"> BinaryTreeNode deleteNode(BinaryTreeNode p){
        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>==p.left&amp;&amp;<span style="color: #0000ff;">null</span>==<span style="color: #000000;">p.right){
            p</span>=<span style="color: #0000ff;">null</span>;<span style="color: #008000;">//</span><span style="color: #008000;">无孩子节点</span>
        }<span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span>(p.left==<span style="color: #0000ff;">null</span><span style="color: #000000;">){
            p</span>=p.right;<span style="color: #008000;">//</span><span style="color: #008000;">只有右孩子</span>
        }<span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span>(p.right==<span style="color: #0000ff;">null</span><span style="color: #000000;">){
            p</span>=p.left;<span style="color: #008000;">//</span><span style="color: #008000;">只有左孩子</span>
        }<span style="color: #0000ff;">else</span><span style="color: #000000;">{
            BinaryTreeNode par</span>=<span style="color: #000000;">p;
            BinaryTreeNode s</span>=<span style="color: #000000;">p.right;
            </span><span style="color: #0000ff;">while</span>(s.left!=<span style="color: #0000ff;">null</span><span style="color: #000000;">){
                par</span>=<span style="color: #000000;">s;
                s</span>=<span style="color: #000000;">s.left;
            }
            p.data</span>=<span style="color: #000000;">s.data;
            </span><span style="color: #0000ff;">if</span>(par==<span style="color: #000000;">p){
                par.right</span>=s.right;<span style="color: #008000;">//</span><span style="color: #008000;">处理特殊情况,par节点没有左孩子</span>
            }<span style="color: #0000ff;">else</span><span style="color: #000000;">{
                par.left</span>=s.right;<span style="color: #008000;">//</span><span style="color: #008000;">处理一般情况,p节点替换成par的最左节点。</span>
    

    }
    }
    return p;
    }

    发散思考-更进一步

      假设一颗二叉树为是一颗右斜树,二叉搜索树的优势也将荡然无存。那问题出在哪?就是构造二叉树的时候,就是我们改善的着手点。

      那么就引出了平衡二叉树的概念,那什么是平衡二叉树呢?

        平衡二叉树或者是一棵空的二叉树,或者是具有以下性质的二叉树。

        根结点的左子树和右子树的深度最多相差1。

        根结点的左子树和右子树也都是平衡二叉树。

      那如何构建一颗平衡二叉树呢?先对数组进行排序,然后像折半查找一样,向两侧平均构造二叉树。当排序的数值多的时候,它将提高查找效率。

      

    //构建平衡搜索二叉树
        public BinaryTreeNode buildBlanceTree(int [] array,int start,int end){
            if(start>end)
                return null;
            int mid=(start+end)/2;
            BinaryTreeNode node=new BinaryTreeNode(array[mid]);
            if(start==end){
                return node;
            }
            node.left=buildBlanceTree(array, start,mid-1);
            node.right=buildBlanceTree(array, mid+1,end);
            return node;
        }

      善于思考的大佬们又脑洞大开了,直接删除节点、插入节点的时候,若产生不平衡,重构平衡二叉树岂不是难上加难?具体代码又读者自行思考完成。

      平衡二叉树分为四种类型:LL型、RR型、LR型、RL型。

      

      LR型:不平衡点的左子树左转,以不平衡点为基点向右转。RL型:不平衡点的右子树右转,以补平衡点为基点向左转。

      

    public class BinaryTreeNode {
        public  int data;
        public BinaryTreeNode left;
        public BinaryTreeNode right;
    
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> BinaryTreeNode() {}
    
    </span><span style="color: #0000ff;">public</span> BinaryTreeNode(<span style="color: #0000ff;">int</span><span style="color: #000000;"> data, BinaryTreeNode left, BinaryTreeNode right) {
        </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
        </span><span style="color: #0000ff;">this</span>.data =<span style="color: #000000;"> data;
        </span><span style="color: #0000ff;">this</span>.left =<span style="color: #000000;"> left;
        </span><span style="color: #0000ff;">this</span>.right =<span style="color: #000000;"> right;
    }
    
    </span><span style="color: #0000ff;">public</span> BinaryTreeNode(<span style="color: #0000ff;">int</span><span style="color: #000000;"> data) {
        </span><span style="color: #0000ff;">this</span>(data,<span style="color: #0000ff;">null</span>,<span style="color: #0000ff;">null</span><span style="color: #000000;">);
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> getData() {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> data;
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> setData(<span style="color: #0000ff;">int</span><span style="color: #000000;"> data) {
        </span><span style="color: #0000ff;">this</span>.data =<span style="color: #000000;"> data;
    }
    
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> BinaryTreeNode getLeft() {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> left;
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setLeft(BinaryTreeNode left) {
        </span><span style="color: #0000ff;">this</span>.left =<span style="color: #000000;"> left;
    }
    
    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> BinaryTreeNode getRight() {
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> right;
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setRight(BinaryTreeNode right) {
        </span><span style="color: #0000ff;">this</span>.right =<span style="color: #000000;"> right;
    }
    

    }

    public class BinarySortTree {

    </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> BinarySortTree(){}
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">构建搜索二叉树</span>
    <span style="color: #0000ff;">public</span>  BinaryTreeNode build(<span style="color: #0000ff;">int</span><span style="color: #000000;"> [] array){
        BinaryTreeNode root </span>=<span style="color: #0000ff;">new</span> BinaryTreeNode(array[0<span style="color: #000000;">]);  
        </span><span style="color: #0000ff;">for</span>( <span style="color: #0000ff;">int</span> i = 1 ; i &lt; array.length ; i ++<span style="color: #000000;">){  
            insertBST(root, array[i]);    
        }
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> root;
    }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">构建平衡搜索二叉树</span>
    <span style="color: #0000ff;">public</span> BinaryTreeNode buildBlanceTree(<span style="color: #0000ff;">int</span> [] array,<span style="color: #0000ff;">int</span> start,<span style="color: #0000ff;">int</span><span style="color: #000000;"> end){
        </span><span style="color: #0000ff;">if</span>(start&gt;<span style="color: #000000;">end)
            </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">;
        </span><span style="color: #0000ff;">int</span> mid=(start+end)/2<span style="color: #000000;">;
        BinaryTreeNode node</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> BinaryTreeNode(array[mid]);
        </span><span style="color: #0000ff;">if</span>(start==<span style="color: #000000;">end){
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> node;
        }
        node.left</span>=buildBlanceTree(array, start,mid-1<span style="color: #000000;">);
        node.right</span>=buildBlanceTree(array, mid+1<span style="color: #000000;">,end);
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> node;
    }
    
    </span><span style="color: #0000ff;">public</span> BinaryTreeNode insertBST(BinaryTreeNode node,<span style="color: #0000ff;">int</span><span style="color: #000000;"> data){
        </span><span style="color: #0000ff;">if</span>(node == <span style="color: #0000ff;">null</span><span style="color: #000000;">){  
            node </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> BinaryTreeNode(data);  
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> node;  
        }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{  
            </span><span style="color: #0000ff;">if</span>(data &lt;=<span style="color: #000000;"> node.data)  
                node.left </span>=<span style="color: #000000;">  insertBST(node.left, data);  
            </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> 
                node.right </span>=<span style="color: #000000;"> insertBST(node.right,data);  
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> node;  
        }  
    }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">层序遍历</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> levelOrder(BinaryTreeNode root){
        BinaryTreeNode temp;
        Queue</span>&lt;BinaryTreeNode&gt; queue=<span style="color: #0000ff;">new</span> LinkedList&lt;BinaryTreeNode&gt;<span style="color: #000000;">();
        queue.offer(root);
        </span><span style="color: #0000ff;">while</span>(!<span style="color: #000000;">queue.isEmpty()){
            temp</span>=<span style="color: #000000;">queue.poll();
            System.out.print(temp.getData()</span>+"	"<span style="color: #000000;">);
            </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>!=<span style="color: #000000;">temp.getLeft()) 
                queue.offer(temp.getLeft());
            </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>!=<span style="color: #000000;">temp.getRight()){
                queue.offer(temp.getRight());
            }
        }
    }
    
    </span><span style="color: #0000ff;">public</span> BinaryTreeNode deleteBST(BinaryTreeNode root,<span style="color: #0000ff;">int</span><span style="color: #000000;"> key){
        </span><span style="color: #0000ff;">if</span>(root==<span style="color: #0000ff;">null</span><span style="color: #000000;">){
            </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">;
        }
        </span><span style="color: #0000ff;">if</span>(root.data==<span style="color: #000000;">key){
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> deleteNode(root);
        }</span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span>(root.data&lt;<span style="color: #000000;">key){
            root.right</span>=<span style="color: #000000;">deleteBST(root.right, key);
        }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{
            root.left</span>=<span style="color: #000000;">deleteBST(root.left, key);
        }
        </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> root;
    }
    
    </span><span style="color: #008000;">//</span><span style="color: #008000;">删除元素</span>
    <span style="color: #0000ff;">public</span><span style="color: #000000;"> BinaryTreeNode deleteNode(BinaryTreeNode p){
        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>==p.left&amp;&amp;<span style="color: #0000ff;">null</span>==<span style="color: #000000;">p.right){
            p</span>=<span style="color: #0000ff;">null</span>;<span style="color: #008000;">//</span><span style="color: #008000;">无孩子节点</span>
        }<span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span>(p.left==<span style="color: #0000ff;">null</span><span style="color: #000000;">){
            p</span>=p.right;<span style="color: #008000;">//</span><span style="color: #008000;">只有右孩子</span>
        }<span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span>(p.right==<span style="color: #0000ff;">null</span><span style="color: #000000;">){
            p</span>=p.left;<span style="color: #008000;">//</span><span style="color: #008000;">只有左孩子</span>
        }<span style="color: #0000ff;">else</span><span style="color: #000000;">{
            BinaryTreeNode par</span>=<span style="color: #000000;">p;
            BinaryTreeNode s</span>=<span style="color: #000000;">p.right;
            </span><span style="color: #0000ff;">while</span>(s.left!=<span style="color: #0000ff;">null</span><span style="color: #000000;">){
                par</span>=<span style="color: #000000;">s;
                s</span>=<span style="color: #000000;">s.left;
            }
            p.data</span>=<span style="color: #000000;">s.data;
            </span><span style="color: #0000ff;">if</span>(par==<span style="color: #000000;">p){
                par.right</span>=s.right;<span style="color: #008000;">//</span><span style="color: #008000;">处理特殊情况,par节点没有左孩子</span>
            }<span style="color: #0000ff;">else</span><span style="color: #000000;">{
                par.left</span>=s.right;<span style="color: #008000;">//</span><span style="color: #008000;">处理一般情况,p节点替换成par的最左节点。</span>
    

    }
    }
    return p;
    }

    </span><span style="color: #008000;">//</span><span style="color: #008000;">查找元素</span>
    <span style="color: #0000ff;">public</span> BinaryTreeNode serachBST(BinaryTreeNode root,<span style="color: #0000ff;">int</span><span style="color: #000000;"> target){
        </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>==<span style="color: #000000;">root)
            </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">;
        </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span>(root.getData()==<span style="color: #000000;">target)
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> root;
        </span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span>(root.getData()&gt;<span style="color: #000000;">target)
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> serachBST(root.getLeft(), target);
        </span><span style="color: #0000ff;">else</span>
            <span style="color: #0000ff;">return</span><span style="color: #000000;"> serachBST(root.getRight(), target);
        
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        </span><span style="color: #0000ff;">int</span> [] array=<span style="color: #0000ff;">new</span> <span style="color: #0000ff;">int</span>[]{11,2,5,7,3,9,4,66,55<span style="color: #000000;">};
        BinarySortTree bst</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> BinarySortTree();
        </span><span style="color: #008000;">//</span><span style="color: #008000;">构建一颗搜索二叉树</span>
        BinaryTreeNode root=<span style="color: #000000;">bst.build(array);
        System.out.println(bst.serachBST(root, </span>9<span style="color: #000000;">).getData());
        bst.levelOrder(root);
        System.out.println();
        
        </span><span style="color: #008000;">//</span><span style="color: #008000;">构建一颗平衡搜索二叉树</span>
    

    Arrays.sort(array);
    BinaryTreeNode node
    =bst.buildBlanceTree(array, 0,array.length-1);
    System.out.println(bst.serachBST(root,
    11).getData());
    bst.levelOrder(node);
    System.out.println();

        BinaryTreeNode n</span>=bst.deleteBST(root,2<span style="color: #000000;">);
        bst.levelOrder(n);
        System.out.println();
    }
    

    }

    搜索二叉树整体代码
  • 相关阅读:
    Windsor
    .net 常见异常及其翻译
    nginx
    数据库访问层封装
    web api HttpConfiguration
    ENode, 领域模型,DDD
    缓存 Redis
    win7 快捷键
    visual studio 快捷键
    c# 正则表达式
  • 原文地址:https://www.cnblogs.com/qiuyong/p/6842414.html
Copyright © 2011-2022 走看看