zoukankan      html  css  js  c++  java
  • 分治法-折半查找和二叉树的相关特性

    4.3 折半查找

    对于有序数组的查找来说,折半查找是一种性能卓越的算法。它通过比较查找健K和数组中间元素A[m]来完成查找工作。如果它们相等,算法结束。否则,如果K<A[m],就对数组的左半部分执行该操作,如果K>A[m],则对数组的右半部分执行该操作。

    折半查找是基于递归思想的,但也可以以迭代方式实现。

    代码实现:

    /**
         * 折半查找(递归方式实现)
         * @author xiaofeig
         * @since 2015.9.16
         * @param array 查找的目标数组
         * @param key 查找键
         * @return 查找成功返回元素下标,查找失败返回-1
         * */
        public static int binarySearchWithRecursion(int[] array,int key){
            int i=array.length/2;
            if(array[i]==key){
                return i;
            }else if(key<array[i]&&i>0){
                return binarySearchWithRecursion(Arrays.copyOfRange(array, 0, i),key);
            }else if(key>array[i]&&i+1<array.length){
                int index=binarySearchWithRecursion(Arrays.copyOfRange(array, i+1, array.length),key);
                return index==-1? index:index+i+1;
            }
            return -1;
        }
        
        /**
         * 折半查找(非递归方式实现)
         * @author xiaofeig
         * @since 2015.9.16
         * @param array 查找的目标数组
         * @param key 查找键
         * @return 查找成功返回元素下标,查找失败返回-1
         * */
        public static int binarySearchWithNonRecursion(int[] array,int key){
            int i=0,j=array.length-1;
            while(i<=j){
                int m=(i+j)/2;
                if(key==array[m]){
                    return m;
                }else if(key<array[m]){
                    j=m-1;
                }else{
                    i=m+1;
                }
            }
            return -1;
        }

    算法分析:

    分析折半查找效率的标准方法是计算查找键和数组元素的比较次数(三路比较次数)。对于一个n元素的数组来说,算法的比较次数不仅是取决于n,而且取决于特定输入的特征。最坏输入包括所有那些不包含查找键K的数组,也包括部分查找成功的。对于最坏情况,有如下关系式:

    当n>1时,Cworst(n)=Cworst(n/2)+1,Cworst(1)=1,即Cworst(n)≈log2n+1≈log2(n+1)

    折半查找的平均效率为:Cavg(n)≈log2n

    折半查找应当看作是一种退化了的分治算法,而更适合归类到减半算法。这里书的作者说道,有时候一个坏的例子比一个好的例子更能够说明一个道理。:-)

    4.4 二叉树遍历及其相关特性

    我们将树的高度定义为从叶子到根之间的最长路径,所以,其值应为其左右子树的最大高度+1。下面代码以递归方式计算树的高度。

    代码实现:

    /**
         * 计算二叉树的高度
         * @author xiaofeig
         * @since 2015.9.18
         * @param binaryTree 要计算高度的目标二叉树
         * @return 空树返回-1,非空树返回树的高度
         * */
        public static int countBinaryTreeHeight(BinaryTree binaryTree){
            if(binaryTree==null)
                return -1;
            int leftSubTreeHeight=countBinaryTreeHeight(binaryTree.getLeftSubTree());
            int rightSubTreeHeight=countBinaryTreeHeight(binaryTree.getRightSubTree());
            return leftSubTreeHeight>rightSubTreeHeight? leftSubTreeHeight+1:rightSubTreeHeight+1;
        }

    (相关的getter和setter略)

    package cn.edu.cqupt.Arithmetic.bean;
    
    public class BinaryTree {
    
        private int value;
        private BinaryTree leftSubTree;
        private BinaryTree rightSubTree;
            
    }

     

    二叉树的遍历:

    二叉树的遍历分为三种:前序遍历、中序遍历、后序遍历,这些都是相对于父节点而言。

    代码实现:

    /**
         * 前序遍历二叉树
         * @author xiaofeig
         * @since 2015.9.18
         * @param binaryTree 要遍历的目标二叉树
         * */
        public static void preOrderTraverseBinaryTree(BinaryTree binaryTree){
            if(binaryTree!=null){
                System.out.print(binaryTree.getValue()+",");
                preOrderTraverseBinaryTree(binaryTree.getLeftSubTree());
                preOrderTraverseBinaryTree(binaryTree.getRightSubTree());
            }
        }
        
        /**
         * 中序遍历二叉树
         * @author xiaofeig
         * @since 2015.9.18
         * @param binaryTree 要遍历的目标二叉树
         * */
        public static void inOrderTraverseBinaryTree(BinaryTree binaryTree){
            if(binaryTree!=null){
                inOrderTraverseBinaryTree(binaryTree.getLeftSubTree());
                System.out.print(binaryTree.getValue()+",");
                inOrderTraverseBinaryTree(binaryTree.getRightSubTree());
            }
        }
        
        /**
         * 中序遍历二叉树
         * @author xiaofeig
         * @since 2015.9.18
         * @param binaryTree 要遍历的目标二叉树
         * */
        public static void postOrderTraverseBinaryTree(BinaryTree binaryTree){
            if(binaryTree!=null){
                postOrderTraverseBinaryTree(binaryTree.getLeftSubTree());
                postOrderTraverseBinaryTree(binaryTree.getRightSubTree());
                System.out.print(binaryTree.getValue()+",");
            }
        }

    宁可孤独,也不违心。宁可抱憾,也不将就。
  • 相关阅读:
    解决无法连接mysql问题
    nodejs基础(二)
    JS面试题
    node初学者笔记
    nodejs安装、环境配置和测试
    Linux常用命令笔记
    MangoDb的安装及使用
    Redis安装、命令以及设置密码遇到的问题
    测试端口通不通问题
    发布版本Debug和Release的区别
  • 原文地址:https://www.cnblogs.com/fei-er-blog/p/4820316.html
Copyright © 2011-2022 走看看