数据结构与算法(JAVA篇)之递归算法(二)

/**
 *
 * @author SunnyMoon
 */

/**
 * 概念介绍:
 * 
 * 递归的二分查找: 想用最少的比较次数在一个有序的数组中找到一个给定的数据项。
 * 
 * 非递归的二分查找:二分查找也可以用非递归的算法,但是分治算法通常要回到递归。分治算
 *                  法常常是一个方法,在这个方法中含有两个对自身的递归的调用。
 * 
 * 分治算法:递归的二分查找是分治算法的一种实现方法。把一个是问题分成两个更小的问题,
 *          并且解决它们。这个过程一直持续下去直到易于求解的基值情况,就不需再分了。
 *          分治算法常常是一上方法,在这个方法中含有两个对自身的递归调用,分别对应于
 *          问题的两个部分。在二分查找中,就有两个这样的调用,但是只有一个真的执行了
 *          (调用哪一个取决于关键字的值)。        
 * 递归的效率:调用一个方法会有一定的代价和开销。首先,控制必须须从当前位置转移到调用
 *            方法的开始处。其次,传给这个方法的参数以及这个方法返回地址都要初压到一
 *            个栈里,为的是方法能够访问参数以及知道返回值在存储在哪里,这个过程也称
 *            "保存现场"。递归方法的使用的本质是从概念上简化了问题,而不是因为它更有
 *            效率。当使用递归的效率很低的时候,就可以考虑如果把递归转化成非递归。
 */
class OrdArray {

    private long[] a;
    private int nElems;

    public OrdArray(int max) {
        a = new long[max];
        nElems = 0;
    }

    public int size() {
        return nElems;
    }

    public int find(long searchKey) {
        return recFind(searchKey, 0, nElems - 1);//调用递归方法
        //return recFind2(searchKey, 0, nElems - 1);//调用非递归方法
    }

    public int recFind(long searchKey, int lowerBound, int upperBound) {//递归方法定义
        int curIn = (lowerBound + upperBound) / 2;
        if (a[curIn] == searchKey) {
            return curIn;
        } else if (lowerBound > upperBound) {
            return nElems;
        } else {
            if (a[curIn] < searchKey) {
                return recFind(searchKey, curIn + 1, upperBound);
            } else {
                return recFind(searchKey, lowerBound, curIn - 1);
            }
        }
    }
    public int recFind2(long searchKey, int lowerBound, int upperBound){//非递归方法定义
        int curIn=0;
        
        while(true){
            curIn=(lowerBound+upperBound)/2;
            if(a[curIn]==searchKey)
                return curIn;
            else if(lowerBound>upperBound)
                return nElems;
            else{
                if(a[curIn]<searchKey){
                    lowerBound=curIn+1;
                }
                else{
                    upperBound=curIn-1;
                }
            }
        }
    }
    public void insert(long value){
        int j;
        for(j=0; j<nElems; j++)
            if(a[j]>value)
                break;
        for(int k=nElems; k>j; k--)
                a[k]=a[k-1];
                a[j]=value;
                nElems++;
    }
    public void display(){
        for(int j=0; j<nElems; j++){
            System.out.println(a[j]+"");
        }
    }
}
class BinarySearchApp{
    public static void main(String[] args){
        int maxSize=100;
        OrdArray arr=new OrdArray(maxSize);
        
        arr.insert(72);
        arr.insert(90);
        arr.insert(45);
        arr.insert(126);
        arr.insert(54);
        arr.insert(99);
        arr.insert(144);
        arr.insert(27);
        arr.insert(135);
        arr.insert(81);
        arr.insert(18);
        arr.insert(100);
        arr.insert(9);
        arr.insert(117);
        arr.insert(63);
        arr.insert(36);
        arr.display();
        
        int searchKey=100;
        if(arr.find(searchKey) !=arr.size())
            System.out.println("Found "+searchKey);
        else
            System.out.println("Can't find "+ searchKey);
    }
}
/**
 * 运行结果:
 * 9
 * 18
 * 27
 * 36
 * 45
 * 54
 * 63
 * 72
 * 81
 * 90
 * 99
 * 100
 * 117
 * 126
 * 135
 * 144
 * Found 100
 */
/**
 * 总结:
 * 很多的数学问题都使用递归的方法解决,比如找两个数的最大公约数,求一个数的
 * 乘方等等。如果有效率需求的时候,可以再考虑将递归转化成非递归。
 */
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值