第二章:排序算法 及其餘 Java代碼實現

第二章:排序算法 及其餘 Java代碼實現

——算法導論(Introduction to Algorithms, Third Edition)算法

插入排序

//打印輸出數組模塊
public class PrintArrays
{
    public static void printA(int []A)
    {
        for (int aInput : A)
        {
            System.out.print(aInput+ "  ");
        }
    }
}
//產生隨機數組模塊
import java.util.*;

public class RandomArray
{
    public static int[] randomArray( int num)
    {
        Random rad =new Random(System.currentTimeMillis());
        int array[] = new int[num];
        for (int i= 0 ; i<num ; i++)
        {
            array[i] = rad.nextInt(100);
        }
        return array;
    }
}
//正常循環迭代實現
public class InsertSort02
{
    public static void main(String args[])
    {
        int A[] = {1,9,6,8,4,5,3,7,2,0};

        for (int j= 0; j<A.length-1 ; j++)
        {
            int key =A[j+1] ;

            int i= j;
            //關鍵性插入
            while ((i >= 0)&&(key< A[i]))
            {
                A[i+1] = A[i];
                i--;
            }
            A[i+1] = key;
        }

        PrintArrays.printA(A);
    }
}
//遞歸實現
public class InsertSort03
{
    public static void main(String srgs[])
    {
        //產生隨機數組
        int A[] =RandomArray.randomArray(8);
        insertSort(A, 0, A.length);
        //輸出數組
        PrintArrays.printA(A);
    }

    //插入排序最後一個參數 r 爲數組長度,p 爲數組起始位置。
    public static void insertSort(int []A,int p, int r)
    {
        // if 用於控制遞歸終止
        if (r >p)
        {
            r--;
            //遞歸拆解
            insertSort(A ,p , r);
            
            int i = r-1;
            int key = A[r];

            //位置插入關鍵
            //邊查找合適的插入位置,邊挪動數組的元素
            while (( i>=p) && (key <A[i]))
            {
                A[i+1] = A[i];
                i--;
            }
            A[i+1] = key;
        } 
    }
}

歸併排序

//常規歸併排序
public class MergeSort01
{
    public static void main(String args[])
    {
        int A[] = RandomArray.randomArray(8);
        mergeSort(A, 0, A.length-1);
        //打印輸出模塊同上
        PrintArrays.printA(A);
    }
    //歸併排序(遞歸調用)
    public static void mergeSort(int A[], int p, int r)
    {
        if ( r>p)
        {
            int q= (p+r-1)/2;
            //方法形參傳遞 爲值傳遞 ,數組形參傳遞的是引用地址
            mergeSort(A, p, q);
            mergeSort(A, q+1,r);
            mergeArray(A, p, q, r);
        }
    }
    //合併子問題的解 模塊
    public static void mergeArray(int A[] , int p,int q,int r) 
    {
        int n1 = q - p + 1;
        int n2 = r - q ;
        int []L = new int[n1];
        int []R = new int[n2];

        for (int i =0; i< n1 ; i++)
        {
            L[i] = A[p+i];
        }

        for (int j =0; j< n1 ; j++)
        {
            R[j] = A[q+j+1];
        }

        for (int k= 0 ,i=0 ,j=0; ((i<n1) || (j<n2))&&(k< r-p+1) ; k++)
        {
            if (i>= n1)
            {
                A[p+k] = R[j];
                j++;
            } else if(j>= n2)
            {
                A[p+k] = L[i];
                i++;
                //以上是其中一個數組遍歷完的處理
            } else if ( L[i]< R[j])
            {
                A[p+k] = L[i];
                i++;
            } else{
                A[p+k] = R[j];
                j++;
            }
        }
    }
}
//歸併排序與插入排序結合
public class MergeSort02
{
    public static void main(String args[])
    {
        //隨機數組的產生
        int A[] = RandomArray.randomArray(128);

        PrintArrays.printA(A);
        System.out.println();

        mergeSort(A, 0, A.length-1, 4);

        //輸出
        PrintArrays.printA(A);

    }
    //歸併排序 參數說明:
    // p 爲數組起始位置    r 爲數組末尾位置       nk 爲子數組插入排序長度
    public static void mergeSort(int A[], int p, int r, int nk)
    {
        int q= (p+r-1)/2;
        if ((q-p+1) > nk)
        {
            //遞歸分解
            mergeSort(A, p, q, nk);
            mergeSort(A, q+1,r, nk);            
        }
         else
         {
            //分治算法 解決最小的子問題
            //插入排序最後一個參數爲數組長度
            InsertSort03.insertSort(A,p ,q +1);
            InsertSort03.insertSort(A,q+1 ,r+1 );
        }
        MergeSort01.mergeArray(A, p, q, r);
        //方法形參傳遞 爲值傳遞 ,數組形參傳遞的是引用地址
        //因爲 數組傳遞引用地址的特性,解決了分治算法的合併子答案步驟
    }
}

選擇排序算法

//選擇排序算法
public class SelectionAlgorithm01
{
    public static void main(String args[])
    {
        int A[] = {1,9,6,8,4,5,3,7,2,0};
        //選擇算法
        //變量 min 依次提取最小值
        for ( int j=1 , k=0; j < A.length ; j++)
        {
            int min = A[j-1] ;
            int i = j;

            //變量 K 用於記錄最小值的位置
            while( i < A.length)
            {
                if( min >A[i])
                {
                    min = A[i];
                    k = i;
                }
                i++;
            }
            A[k] = A[j-1];
            A[j-1] = min;

        }
        // 4 重複
        PrintArrays.printA(A);
    }
}

冒泡排序

public class BubbleSort
{
    //冒泡排序法
    public void maoPaoPX(int[] arryA)
    {
        //將最大的依次 冒泡到最右邊
        for (var i=arryA.length; i>0;i--)
        {
            for (var j=0;j<i;j++)
            {

                if ((j+1)==arryA.length)
                {
                    break;
                }
                if ( arryA[j] > arryA[j+1] )
                {
                    int temp = arryA[j+1];
                    arryA[j+1] =arryA[j];
                    arryA[j] =temp;
                }
            }
        }
    }
}

查找算法

//查找算法
public class LinearSearch
{
    static final int  NIL = -1 ;

    public static void main(String args[])
    {
        int v = 8;
        int []A = {1,9,6,8,4,5,3,7,2,0};

        //排序
        A = InsertSort03.insertSort(A, A.length);
        PrintArrays.printA(A);
        System.out.println();
        //線性查找
        int j = linearSearch(A , v);
        System.out.println("j = "+ j);
        //二分法查找
        j= binarySearch02(A , v, 1 ,A.length ,1 ) ;
        System.out.println("j = "+ j);

        /*
        j= binarySearch(A , v , true , 0, A.length-1);
        System.out.println("j = "+ j);
        */
    }

    //二分法查找
    public static int binarySearch02(int []A,int v , int left,int right ,int mid)
    {
        mid = (left+ right)/2;
        int aMid= mid -1;
        if (A[aMid] ==  v)
        {
            return mid;
        } else if( A[aMid] > v){
            right = mid;
        }else {
            left = mid;
        }
        return binarySearch02(A , v ,left ,right ,mid);
    }
    //線性查找
    public static int linearSearch(int []A, int v)
    {
        int i=1;
        int j=NIL;

        for (int atemp : A)
        {
            if( atemp == v)
            {
                j=i ;
            }
            i++;
        }
        return j;
    }
}

習題 2.3.7

public class BookTest2o3o7
{
    public static void main(String args[])
    {
        int A[] = {2 , 4, 5,6, 8, 10};
        int x= 17;

        System.out.println(bookTest2o3o7(A, x));
    }

    /*
        描述一個運行時間爲@(nlgn) 的算法,給定n 個整數的集合S 和另外一個整數X , 該算法能
    肯定S 中是否存在兩個元素其和恰好爲x的元素。
    */
    public static boolean bookTest2o3o7(int []A, int x)
    {
        if (A.length <=1)
        {
            return false;
        }

        int i=0;
        int j= A.length-1;
        while(i<j)
        {
            //x 與 A[i]+A[j] 比較。
            //若 x 較大,則 i 增大 ,不然 j 減少,直到 i >= j 結束循環。
            if (x ==(A[i] + A[j]) )
            {
                return true;
            } else if( x > A[i] + A[j]){
                i++;
            } else {
                j--;
            }
        }
        return false;
    }
}
相關文章
相關標籤/搜索