1. 程式人生 > >荷蘭國旗問題和快速排序

荷蘭國旗問題和快速排序

1、 題目一:

給定一個數組arr和一個數num,讓大於這數的數字放在陣列的右邊,小於等於這個數字放在陣列的左邊。 要求:時間複雜度O(n),額外空間複雜度O(1)

/*我的程式碼*/
public class exercise__1 {
    public static void sort_num(int[] arr,int num){
        int left_sub=0;
        int right_sub=arr.length-1;
        for (int i = 0; i<arr.length; i++) {
            if (arr[left_sub] <=num) {
                left_sub=left_sub+1
; continue; } if(arr[right_sub]>num){ right_sub=right_sub-1; continue; } swap(arr,left_sub,right_sub); left_sub=left_sub+1; right_sub=right_sub-1; if (left_sub==right_sub){ break
; } } } public static void swap(int[] arr,int left,int right){ int station=arr[left]; arr[left]=arr[right]; arr[right]=station; } public static void main(String[] args) { int[]arr={1,50,20,67,69,82,11,3,59,70,3,4,2,1,1,0}; sort_num(arr,50
); for (int i = 0; i < arr.length-1; i++) { System.out.println(arr[i]); } } }
code2
/*演算法*/
class niu_sortnum{
    public static void  sortnum(int[] arr,int num){
        int small_index=-1;
        for (int i = 0; i <arr.length ; i++) {
            if (arr[i]<=num){
                swap(arr,++small_index,i);
            }
        }
    }
    public static  void swap(int[] arr,int left,int right){

        int station=arr[left];
        arr[left]=arr[right];
        arr[right]=station;
    }
    public static void main(String[] args) {
        int[] arr={1,4,5,7,9,10,100,300,400,500,1000,1,2,4,7,123,300,1,9};
        sortnum(arr,100);
        for (int i=0;i<arr.length-1;i++){
            System.out.println(arr[i]);
        }
    }

2、題目二:(荷蘭國旗問題)

給定一個數組arr,和一個數num,請把小於num的數放在陣列的左邊,等於num的書放在中間,大於num的數放在右邊。 要求:時間複雜度O(n),額外空間複雜度O(1)

class exercise2{
//    small、big分別指向陣列的最-1和arr.length的下標,使用current變數作為遍歷陣列的下標
//    如果arr[cuurrent]<num;交換swap(arr[++small],arr[curent]),small右移動一位,current++
//    如果arr[cuurrent]==num;不做任何處理,current++繼續向右遍歷
//    如果arr[cuurrent]>num;交換swap(arr[--big],arr[curent]),big左移動一位,current不移動,
    //迴圈終止條件current==big
    public static void sortnum(int[] arr,int num){
        int small=-1;
        int big=arr.length;
        int current=0;
        while(current!=big) {
            if (arr[current]<num){
                swap(arr,++small,current++);

            }
            else if (arr[current]==num){
                current++;

            }
            else if(arr[current]>num){
                swap(arr,--big,current);
            }
        }

    }
    public static  void swap(int[] arr,int left,int right){

        int station=arr[left];
        arr[left]=arr[right];
        arr[right]=station;
    }
    public static void main(String[] args) {
        int[] arr={1,3,50,500,9,0,60,70,50,51,81,1,5,8,100};
        sortnum(arr,50);
        for (int i = 0; i <arr.length ; i++) {
            System.out.println(arr[i]);
        }
    }
}

3、經典快速排序

快速排序(經典快排)

import java.util.Arrays;

/*
快速排序(經典快排)
·選取第一個數(或最後一個數)作為基準,把它放在陣列的中,陣列一分為二,左邊的數比它小右邊的數比它大
·將左邊的部分遞迴
·將右邊的部分遞迴
 */
public class quickSort {
    public  static void QuickSort(int[] A,int p,int r){//p,r分別為陣列的首元素和尾元素下標
        if (p<r){
            int q=Partition(A,p,r);//劃分陣列,找到首元素A[p]在排好序後的位置q
            swap(A,p,q);
            QuickSort(A,p,q-1);
            QuickSort(A,q+1,r);
        }
    }
    public static void swap(int[] arr,int a,int b){
        int tem=arr[a];
        arr[a]=arr[b];
        arr[b]=tem;
    }
    public static int Partition(int []A,int p,int r){
        /*
        輸入:陣列A[p,r];
        輸出:j,,A的首元素在排好序的陣列中的位置
         */
        int key=A[p];
        int i=p;
        int j=r;
        while (i<j){
           /*從左向右遍歷*/
            while (A[i]<=key){
                i=i+1;
            }
            /*從右向左遍歷*/
            while(A[j]>key){
                j=j-1;
            }
            if (i<j){
                swap(A,i,j);
            }
        }
        return j;
    }
    public static void main(String[] args) {
        int[] arr= {27, 99, 30, 1, 0, 9, 38, 57, 90, 1, 27, 30, 8};
        System.out.println(Arrays.toString(arr));
        QuickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));

    }
}

4、隨機快排

import java.util.Arrays;
public class random_quicksort {
    public static void  quickSort(int []arr,int L,int R){
        if (L<R){
            /*
            Math.random返回>=0,小於R-L+1的數
             */
            swap(arr, L+(int) Math.random()*(R-L+1),R);
            int[]p=partition(arr,L,R);
            quickSort(arr,L,p[0]-1);
            quickSort(arr,p[1]+1,R);
        }
    }
    public static int[] partition(int[] arr, int L, int R){
        int small=L-1;
        int big=R;
        int key=arr[R];
        int current=L;
        while(current<big) {
            if (arr[current]<key){
                swap(arr,++small,current++);
            }
            else if(arr[current]>key){
                swap(arr,--big,current);
            }
            else{
                current++;
            }
        }
        swap(arr,R,big);
        return new int[]{small+1,big};
    }
    public static  void swap(int[] arr,int a,int b){
        int station=arr[a];
        arr[a]=arr[b];
        arr[b]=station;
    }
    public static void main(String[] args) {
        int[] arr={40,3,50,500,9,0,60,70,50,51,81,1,5,8,100};
        System.out.println(Arrays.toString(arr));
        quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
}

5、根據荷蘭國旗改進後的快排

import java.util.Arrays;
public class quickSort_modify {
    public static void  quickSort(int []arr,int L,int R){
        if (L<R){
            int[]p=partition(arr,L,R);
            quickSort(arr,L,p[0]-1);
            quickSort(arr,p[1]+1,R);
        }
    }
    public static int[] partition(int[] arr, int L, int R){
        int small=L-1;
        int big=R;
        int key=arr[R];
        int current=L;
        while(current<big) {
            if (arr[current]<key){
                swap(arr,++small,current++);
            }
            else if(arr[current]>key){
                swap(arr,--big,current);
            }
            else{
                current++;
            }
        }
        swap(arr,R,big);
        return new int[]{small+1,big};
    }
    public static  void swap(int[] arr,int a,int b){
        int station=arr[a];
        arr[a]=arr[b];
        arr[b]=station;
    }
    public static void main(String[] args) {
        int[] arr={40,3,50,500,9,0,60,70,50,51,81,1,5,8,100};
        System.out.println(Arrays.toString(arr));
        quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
}

6、快排的非遞迴實現


import java.util.Stack;

public class not_recursion_quicksort {
    public static void main(String[] args) {
        int[] array = { 3, 2, 11, 121,2,32,545,3434,222,18, 99, 233, 53, 101, 22, 9, 100 };
//        partition(array,0,array.length-1);
      not_recursion_quicksort.sort(array);
        for (int num:array) {
            System.out.print(num + " ");
        }
    }
    public static void sort(int[] array) {
        if (array == null || array.length == 1)
            return;
        //棧頂的兩個元素存放要partition的最左座標和最右座標
        Stack<Integer> s = new Stack<Integer>();
        //初始化最左和最右座標,即0和len-1
        s.push(0);
        s.push(array.length - 1);

        //迴圈,結束條件為棧空
        while (!s.empty()) {
            int right = s.pop();
            int left = s.pop();    //棧頂兩個元素出棧
            //右邊索引小於等於左邊索引了,不需要調整,僅需要出棧,結束
            if (right <= left)
                continue;
            int i = partition(array, left, right);
            //右半部分入棧
            s.push(i+1);
            s.push(right);
            //左半部分入棧
            s.push(left);
            s.push(i-1);
        }
    }
    //將pivot放到最終位置,並且左邊的元素都小於等於pivot,右邊的元素都大於等於pivot
    public static int partition(int[] a, int left, int right){
        int i = left,j=right;
        int pivot = a[right];                //將pivot暫存,因為之後這個位置將由比pivot小的數佔據
        while(i!=j){
            for(;i<j && a[i]<=pivot;i++);   //從左邊找一個比pivot大的數
                a[j] = a[i];                    //將這個數放到右邊空位
            for(;i<j && a[j]>=pivot;j--);   //從右邊找一個比pivot小的數
            a[i] = a[j];                    //將這個數放到左邊空位,空位是由pivot或之前比pivot大的數留出來的
        }
        a[i] = pivot;
        return i;
    }
}