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();
    }
    

    }

    搜索二叉树整体代码
  • 相关阅读:
    Oracle 11g SQL Fundamentals Training Introduction02
    Chapter 05Reporting Aggregated data Using the Group Functions 01
    Chapter 01Restriicting Data Using The SQL SELECT Statemnt01
    Oracle 11g SQL Fundamentals Training Introduction01
    Chapter 04Using Conversion Functions and Conditional ExpressionsConditional Expressions
    Unix时代的开创者Ken Thompson (zz.is2120.bg57iv3)
    我心目中计算机软件科学最小必读书目 (zz.is2120)
    北京将评估分时分区单双号限行 推进错时上下班 (zz)
    佳能G系列领军相机G1X
    选购单反相机的新建议——心民谈宾得K5(转)
  • 原文地址:https://www.cnblogs.com/qiuyong/p/6842414.html
Copyright © 2011-2022 走看看