数据结构与算法(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  
 */  
/**  
 * 总结:  
 * 很多的数学问题都使用递归的方法解决,比如找两个数的最大公约数,求一个数的  
 * 乘方等等。如果有效率需求的时候,可以再考虑将递归转化成非递归。  
 */ 
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号