Java基礎---折半查找和進制轉換

折半查找:

說明:插入和進制轉換用到了 數組的操作,就當對數組進一步瞭解了。

要求:一定是對有序序列的查找

/* 
需求:將一個已知元素插入到一個有序數組中,要求不改變數組順序,打印元素應該插入數組位置的角標。 
思路:1、可以利用折半查找的方式,先定義兩個變量,一個初始化0角標,作爲最小值,一個初始化爲最後一個角標,作爲最大值, 
        再定義一個變量,存儲最小值與最大值的一半,也就是中間位置,然後將已知元素與中間值位元素進行比較。 
      2、如果比中間值元素大,則將最小值變爲中間值加1,繼續取最小值與最大值的中間值元素與已經元素進行比較,以此反覆 
      3、如果比中間值元素小,則將最大值變爲中間值減1,繼續取最小值與最大值的中間值元素與已經元素進行比較,以此反覆 
*/  
public class BinarySearch1
{
    /***************************
    折半查找 Version-1.0
    這個折半查找我在寫的時候有一點問題,
    問題一:if(min>max)這句話的判斷不能直接放在開頭,因爲如果查詢的數小於頭會報數組越界錯誤
    原因:此時max已經指向-1,所以mid取-1,所以越界了
    ***************************/
    public static int binarySearch1(int key,int arr[])
    {
        int min = 0;
        int max = arr.length-1;
        int mid = (min+max)/2;
        while(key!=arr[mid])
        {
            //位置1:
            //if(min>max)
            //{
            //  return -1;
            //}
            mid = (min+max)/2;
            if(key>arr[mid])
            {
                min = mid + 1;
            }else if(key<arr[mid])
            {
                max = mid - 1;
            }
            if(min>max)
            {
                return -1;
            }
            mid = (min+max)/2;
        }
        return mid;
    }
    /*
    折半查找 version-2.0
    這種方法不會出現問題一,因爲一旦min>max了,就跳出循環了,不會出現越界問題了
    */
    public static int binarySearch2(int key,int arr[])
    {
        int min = 0;
        int max = arr.length-1,mid;
        while(min<=max)
        {
            mid = (min+max)>>>1;
            if(key>arr[mid])
            {
                min = mid + 1;
            }else if(key<arr[mid])
            {
                max = mid - 1;
            }else
            {
                return mid;
            }
        }
        return -1;
    }
    public static void main(String []args)
    {
        int arr1[] = {0,3,7,9,11,12,14,70,80,90,100};
        int key = 3;//11,100

        int y = binarySearch1(key,arr1);
        int z = binarySearch2(key,arr1);
        System.out.println("使用版本1.0,查詢到的腳標數的腳標是:"+y);
        System.out.print("使用版本2.0,查詢到的腳標數的腳標是:"+z);
    }
}

結果是:
binarysearch1

折半查找的插入點返回

如果查找的數字是不存在的,我想知道他可以插在那個地方:
先要知道一個概念,如果沒有查到想要的數,那麼min和max指向哪裏?

畫圖理解二分法插入:
這裏寫圖片描述
那麼根據上面的查找,只需將return -1改爲return min;就可以了!

public class BinarySearch1
{
    //二分查找法改進爲可以找不存在的數的插入點
    public static int binarySearch2(int key,int arr[])
    {
        int min = 0;
        int max = arr.length-1,mid;
        while(min<=max)
        {
            mid = (min+max)>>>1;
            if(key>arr[mid])
            {
                min = mid + 1;
            }else if(key<arr[mid])
            {
                max = mid - 1;
            }else
            {
                return mid;
            }
        }
        //修改這裏的返回值
        return min;
    }
    public static void main(String []args)
    {
        int arr1[] = {0,3,7,9,11,12,14,70,80,90,100};
        int key = 5;
        int z = binarySearch2(key,arr1);
        System.out.println("使用版本2.0,查詢數:"+key+" 的腳標是:"+z);
        int a = Arrays.binarySearch(arr1, key);
        System.out.println("使用Arrays下的方法,查找 "+key+" 的腳標是:"+a);
    }
}

運行:
這裏寫圖片描述

這裏根據java.util.Arrays類的方法binarySearch進行比較,感覺人家寫得好啊,我這個找出來的不知道是查到了還是插入點,人家的方法清楚,正數是查到的腳標,負數時將插入的腳標。

優化:將return min;可以改寫爲return -1-min。結果就和他的一樣了。

進制轉換

十進制轉十六進制:

/* 
使用查表法將十進制轉換爲十六進制 
*/  
public class ToHex1
{
    public static char[] toHex(int num)
    {
        if(num==0)
        {
            char []c1 = {'0'};
            return c1;
        }
        //定義一個包含二進制、八進制、十六進制的表 
        char hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        //定義一個臨時容器  
        char c[] = {'0','0','0','0','0','0','0','0'};
        //定義一個操作數組的指針  
        int  i = c.length;
        //利用與低位最大值的方式取出低位,存到臨時數組中  
        while(num!=0)
        {
            c[--i] = hex[num&15];//--pos倒着往臨時容器裏存  
            num = num>>>4;//無條件右移相應位數  
        }
        return c;
    }
    public static void main(String args[])
    {
        int a = 60;
        System.out.print(toHex(a));
    }
}

結果:
tohex1

十進制轉二進制,八進制,十六進制

將以上方法封裝升級,轉換成可以重複利用,並可以實現十進制轉二進制和八進制:
public class ToHex1
{
    //抽象出來的方法,base是“與(&)”的對象,move是移動的位數
    public static void convert(int num ,int base,int move)
    {
    //0比較特殊,需要特殊對待
        if(num==0)
        {
            char []c1 = {'0'};
            System.out.print("0");
            return;
        }
        char hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        char c[] = new char[32];
        int  i = c.length;
        while(num!=0)
        {
            c[--i] = hex[num&base];
            num = num>>>move;
        }
        for(int j=i;j<c.length;j++)
        {
            System.out.print(c[j]);
        }
    }

    //轉二進制
    public static void toBinary(int num)
    {
        convert(num,1,1);
        //換行
        System.out.println();
    }

    //轉八進制
    public static void toOctal(int num)
    {
        convert(num,7,3);
        //換行
        System.out.println();
    }

    //轉十六進制
    public static void toHex(int num)
    {
        convert(num,15,4);
        //換行
        System.out.println();
    }

    public static void main(String args[])
    {
        int a = 60;
        System.out.print("數"+a+"對應二進制:");
        toBinary(a);
        System.out.print("數"+a+"對應八進制:");
        toOctal(a);
        System.out.print("數"+a+"對應十六進制:");
        toHex(a);
    }
}

運行結果(0和60):
converttoall1

總結:

1.折半查找的思想
2.對摺半查找的min和max的理解可以推導出:對不存在數的插入位置的推斷。
3.進制轉換,“與(&)”的運用,取位操作。
發佈了21 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章