旋轉數組查找, 二分查找的遞歸於非遞歸實現

package java_study.JianZhiOffer;

import org.junit.Test;

import java.util.Arrays;

/**
 * Created by ethan on 2015/6/22.
 * 劍指offer 第八題 旋轉數組查找
 * 查找算法中重要的:二分,hash,二叉搜索樹
 * 排序中重要的算法:快排的partition思路(一次可以定位一個值), 堆排序(選出最小的or最大的幾個), 歸併排序(n個有序子序列)
 * 插入排序:保證前n位是有序的, 希爾排序:間隔有序子序列, 冒泡排序: 能挑出最大or最小的幾位數放到最後,但是效率比堆排序低, 選擇排序:找出最大or最小放在最前or最後
 */
public class No8RotateTheMini {
    // 原始的二分查找
    public boolean binaryFind(int[] arr, int goal){
        return binaryFindImpl(arr, goal, 0, arr.length-1);
    }
    // 遞歸實現
    public boolean binaryFindImpl(int[] arr, int goal, int first, int last){
        if (arr==null) return false;
        if (first<0 || last<0 || first>last) return false;
        int mid = (first+last)/2;
        if (arr[mid]==goal) return true;
        else if (arr[mid]<goal) return binaryFindImpl(arr, goal, mid + 1, last);
        else return binaryFindImpl(arr, goal, first, mid - 1);
    }
    // 非遞歸實現
    public boolean binaryFindNoRecursive(int[] arr, int goal){
        if (arr==null) return false;
        int first = 0;
        int end = arr.length-1;
        while (first<=end){
            int mid = (first+end)/2;
            if (arr[mid]==goal)
                return true;
            else if(arr[mid] < goal)
                first = mid+1;
            else
                end = mid-1;
        }
        return false;
    }
    // 對於旋轉數組
    public int binaryFindRotation(int[] arr, int goal){
        return binaryFindRotationInpl(arr, goal, 0, arr.length-1);
    }
    public int binaryFindRotationInpl(int[] arr, int goal, int first, int end){
        if (arr==null) return -1;
        if (first<0 || end<0 || first>end) return -1;
        int mid = (first+end)/2;
        if (arr[mid] == goal) return mid;
        else {
            if (arr[mid] > arr[first]){
                if (arr[mid]>goal && arr[first]<=goal) return binaryFindRotationInpl(arr, goal, first, mid - 1);
                else return binaryFindRotationInpl(arr, goal, mid+1, end);
            }else {
                if (arr[mid]<goal && arr[end]>=goal) return binaryFindRotationInpl(arr, goal, mid+1, end);
                else return binaryFindRotationInpl(arr, goal, first, mid-1);
            }
        }
    }
    // 旋轉數組找出最小的數
    public int findRotationSortedArray(int[] arr){
        return findRotationSortedArrayImpl(arr,  0, arr.length-1);
    }
    public int findRotationSortedArrayImpl(int[] arr, int first, int last){
        if (arr==null || first<0 || last<0 || first>last) return -1;
        if (last-first==1)
            return last;
        int mid = (first+last)/2;
        if (arr[first] < arr[mid]) return findRotationSortedArrayImpl(arr,  mid, last);
        else return findRotationSortedArrayImpl(arr, first, mid);
    }

    @Test
    public void test(){
        int[] arr = {23, 22, 81, 33, 67, 54, 92, 10, 3};
        Arrays.sort(arr);
        System.out.println(binaryFind(arr, 81));
        System.out.println(binaryFindNoRecursive(arr, 81));
        int[] arr1 = {10, 29, 32, 35, 42, 50, -1, 1, 5, 8, 9};
        System.out.println(binaryFindRotation(arr1, 31));
        System.out.println(findRotationSortedArray(arr1));
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章