1. 程式人生 > 其它 >linux如何把新加的分割槽掛載到/根目錄

linux如何把新加的分割槽掛載到/根目錄

排序大的分類可以分為兩種:內排序和外排序。在排序過程中,全部記錄存放在記憶體,則稱為內排序。如果排序過程中需要使用外存,則稱為外排序。下面講的排序都是屬於內排序。


一、插入排序

(一)、直接插入排序

public class Sort {
    public static void main(String[] args) {
        int[] arr = {1, 3, 51, 65, 6, 34, 67, 343, 56};
        int[] sortResult = insertionSort(arr);
        System.out.println(Arrays.toString(sortResult));
    }

    
/** * 用一個臨時變數儲存待插入的值,從後往前找,如果找到比這個值大的元素,則將其前面的元素依次後移, * 結束後再將帶插入的值放到該插入的位置,減去了許多不必要的交換操作 * @param arr * @return */ public static int[] insertionSort(int[] arr) { for (int i = 1; i < arr.length; i++) { //待插入元素 int insertValue = arr[i];
int preIndex = i - 1; while (preIndex >= 0 && insertValue < arr[preIndex]) { arr[preIndex + 1] = arr[preIndex]; preIndex--; } arr[preIndex + 1] = insertValue; } return arr; } }

(二)、希爾排序(shell排序)

public
class Sort { public static void main(String[] args) { int[] arr = {1, 3, 51, 65, 6, 34, 67, 343, 56}; int[] sortResult = shellSort(arr); System.out.println(Arrays.toString(sortResult)); } /** * 希爾排序 * 插入排序的升級版,設定步長為陣列長度的一半,每次都除以二,直到步長為1 * @param arr * @return */ public static int[] shellSort(int[] arr) { int len = arr.length; for (int k = len / 2; k > 0; k /= 2) { for (int i = k; i < len; i++) { int temp = arr[i]; int j = i - k; while (j >= 0 && temp < arr[j]) { arr[j + k] = arr[j]; j -= k; } arr[j + k] = temp; } } return arr; } }

二、選擇排序

(一)、簡單選擇排序(直接排序)

public class Sort {
    public static void main(String[] args) {
        int[] arr = {1, 3, 51, 65, 6, 34, 67, 343, 56};
        int[] sortResult = selectionSort(arr);
        System.out.println(Arrays.toString(sortResult));
    }

    /**
     * 遍歷陣列,每次遍歷都找到最小的元素,記錄其下標,內層迴圈結束後再根據下標將其與陣列頭部元素交換
     * 與氣泡排序不同的是,氣泡排序每次迴圈可能交換多次,而選擇排序最多交換一次
     * @param arr 待排序陣列
     * @return
     */
    public static int[] selectionSort(int[] arr) {
        int temp, minIndex;
        for (int i = 0; i < arr.length - 1; i++) {
            minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            temp = arr[minIndex];
            arr[minIndex] = arr[i];
            arr[i] = temp;
        }
        return arr;
    }
}

(二)、堆排序

public class HeapSort {

    public static void main(String[] args) {
        int[] arr = {1, 3, 51, 65, 6, 34, 67, 343, 56};
        int[] sortResult = heapSort(arr);
        System.out.println(Arrays.toString(sortResult));
    }

    public static int[] heapSort(int[] arr) {
        //以最後一個非葉子結點構建大頂堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            adjustHeap(arr, i, arr.length);
        }
        //此時頂部元素是最大的,交換頂部元素和末端元素
        for (int i = arr.length - 1; i > 0; i--) {
            swap(arr, 0, i);
            //末端元素已經是最大的了,無需考慮排序
            adjustHeap(arr, 0, i);
        }
        return arr;
    }

    /**
     * 形成大頂堆
     *
     * @param arr 陣列元素
     * @param i   當前結點位置
     * @param len 結點個數
     */
    public static void adjustHeap(int[] arr, int i, int len) {
        //儲存當前結點
        int temp = arr[i];
        //遍歷當前結點的左子結點
        for (int k = 2 * i + 1; k < len; k = 2 * k + 1) {
            //如果右結點存在 且 右結點比左結點大,指向右結點
            if (k + 1 < len && arr[k] < arr[k + 1]) {
                k++;
            }
            //判斷當前結點和左(右)結點哪個大
            if (temp < arr[k]) {
                //交換
                swap(arr, k, i);
                //交換後,下次遍歷以該子結點作為根節點的子樹就會受到影響,因此需要重新指定下次的根節點
                i = k;
            } else {
                //不用交換,直接終止迴圈
                break;
            }
        }
    }

    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

三、交換排序

(一)、氣泡排序

/**
 * 遍歷陣列,依次比較相鄰的元素並交換,每次都將最大元素(根據正序還是逆序決定)放到陣列末尾
 * @param arr 待排序陣列
 * @return
 */
public static int[] bubbleSort(int[] arr) {
    int temp;

    for (int i = 0; i < arr.length - 1; i++) {
        for (int j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                temp = arr[j + 1];
                arr[j + 1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}

氣泡排序優化一:

//氣泡排序:優化一
public static int[] bubbleSort1(int[] arr) {
    int temp;
    //記錄陣列是否有序
    boolean isSorted;

    for (int i = 0; i < arr.length - 1; i++) {
        isSorted = true;
        for (int j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                temp = arr[j + 1];
                arr[j + 1] = arr[j];
                arr[j] = temp;
                //記錄本輪排序是否交換了元素,如果交換則置為false
                isSorted = false;
            }
        }
        //沒有交換證明已經是有序的了,直接終止迴圈
        if (isSorted) {
            break;
        }
    }
    return arr;
}

氣泡排序優化二:

//氣泡排序:優化二
public static int[] bubbleSort2(int[] arr) {
    int temp;
    boolean isSorted;
    //第一次迴圈邊界
    int sortBorder = arr.length - 1;
    //記錄每輪排序最後一次進行交換的位置
    int lastSwapIndex = 0;

    for (int i = 0; i < arr.length - 1; i++) {
        isSorted = true;
        for (int j = 0; j < sortBorder; j++) {
            if (arr[j] > arr[j + 1]) {
                temp = arr[j + 1];
                arr[j + 1] = arr[j];
                arr[j] = temp;
                isSorted = false;
                lastSwapIndex = j;
            }
        }
        sortBorder = lastSwapIndex;
        if (isSorted) {
            break;
        }
    }
    return arr;
}

(二)、快速排序

演算法原理:先在陣列中選擇一個數字,通過一趟排序將要排序的資料分割成獨立的兩部分:比選擇的數字小的數字都移到陣列的左邊,比選擇的數字大的數字都移到陣列的右邊。然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。

快速排序中基準的選取:
1. 第一個元素或最後一個元素,但是當陣列中的元素原本為逆序時,升序排序就會變成一次只能確定基準元素的位置,無法發揮快排的優勢
2. 隨機選取
3. 三數取中法,也就是取左端、中間、右端三個數,然後進行排序,將中間數作為樞紐值。

舉個栗子:

原陣列:{3,7,2,9,1,4,6,8,10,5}
期望結果:{1,2,3,4,5,6,7,8,9,10}

快速排序示意圖:

程式碼實現:

public class QuickSort {
    
    public static int divide(int[] a, int start, int end){
        //每次都以最右邊的元素作為基準值
        int base = a[end];
        //start一旦等於end,就說明左右兩個指標合併到了同一位置,可以結束此輪迴圈。
        while(start < end){
            while(start < end && a[start] <= base)
                //從左邊開始遍歷,如果比基準值小,就繼續向右走
                start++;
            //上面的while迴圈結束時,就說明當前的a[start]的值比基準值大,應與基準值進行交換
            if(start < end){
                //交換
                int temp = a[start];
                a[start] = a[end];
                a[end] = temp;
                //交換後,此時的那個被調換的值也同時調到了正確的位置(基準值右邊),因此右邊也要同時向前移動一位
                end--;
            }    
            while(start < end && a[end] >= base)
                //從右邊開始遍歷,如果比基準值大,就繼續向左走
                end--;
            //上面的while迴圈結束時,就說明當前的a[end]的值比基準值小,應與基準值進行交換
            if(start < end){
                //交換
                int temp = a[start];
                a[start] = a[end];
                a[end] = temp;
                //交換後,此時的那個被調換的值也同時調到了正確的位置(基準值左邊),因此左邊也要同時向後移動一位
                start++;
            }    
            
        }
        //這裡返回start或者end皆可,此時的start和end都為基準值所在的位置
        return end;
    }
 
    /**
     * 排序
     * @param a
     * @param start
     * @param end
     */
    public static void sort(int[] a, int start, int end){
        if(start > end){ //start >= end ?
            //如果只有一個元素,就不用再排下去了
            return;
        } 
        else{
            //如果不止一個元素,繼續劃分兩邊遞迴排序下去
            int partition = divide(a, start, end);
            sort(a, start, partition-1);
            sort(a, partition+1, end);
        }
            
    }


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] a = new int[]{2,7,4,5,10,1,9,3,8,6};
        int[] b = new int[]{1,2,3,4,5,6,7,8,9,10};
        int[] c = new int[]{10,9,8,7,6,5,4,3,2,1};
        int[] d = new int[]{1,10,2,9,3,2,4,7,5,6};
        int[] e = {3};
            
        sort(b, 0, b.length-1);
            
        System.out.println("排序後的結果:");
        for(int x : b){
            System.out.print(x+" ");
        }

    }

}

四、歸併排序

public class Sort {
    public static void main(String[] args) {
        int[] arr = {1, 3, 51, 65, 6, 34, 67, 343, 56};
        int[] sortResult = mergeSort(arr);
        System.out.println(Arrays.toString(sortResult));
    }

    //歸併排序
    public static int[] mergeSort(int[] arr) {
        return mergeSort(arr, 0, arr.length - 1, new int[arr.length]);
    }

    /**
     * 歸併排序通過遞迴將陣列分解為只有兩個元素,按照它們的大小放入到一個臨時陣列中,直到全部合併
     *
     * @param arr   待排序陣列
     * @param left  左索引
     * @param right 右索引
     * @param temp  臨時陣列,儲存每次合併後的元素
     * @return
     */
    public static int[] mergeSort(int[] arr, int left, int right, int[] temp) {
        if (left < right) {
            int mid = (left + right) >> 1;
            //向左分解
            mergeSort(arr, left, mid, temp);
            //向右分解
            mergeSort(arr, mid + 1, right, temp);
            //合併
            merge(arr, left, mid, right, temp);
        }
        return arr;
    }

    //合併
    public static int[] merge(int[] arr, int left, int mid, int right, int[] temp) {
        int i = left, j = mid + 1, k = 0;
        //按大小放入臨時陣列中
        while (i <= mid && j <= right) {
            if (arr[i] < arr[j]) {
                temp[k] = arr[i];
                k++;
                i++;
            } else {
                temp[k] = arr[j];
                k++;
                j++;
            }
        }

        //將剩餘元素放到temp剩餘位置
        while (i <= mid) {
            temp[k] = arr[i];
            k++;
            i++;
        }
        while (j <= right) {
            temp[k] = arr[j];
            k++;
            j++;
        }

        //將排好序的temp陣列元素賦值給原陣列
        k = 0;
        int l = left;
        while (l <= right) {
            arr[l] = temp[k];
            k++;
            l++;
        }

        return arr;
    }

}

五、基數排序

public class RadixSort {

    public static void main(String[] args) {
        int[] arr = {1, 3, 51, 65, 6, 34, 67, 343, 56};
        int[] sortResult = radixSort(arr);
        System.out.println(Arrays.toString(sortResult));
    }

    /**
     * 基數排序:
     * 根據每個數的個位、十位、百位...的值(0~9)放入桶中(規則和計數排序相同),因此需要10個桶
     *
     * @param arr
     * @return
     */
    public static int[] radixSort(int[] arr) {
        //建立並初始化10個桶
        ArrayList<LinkedList<Integer>> bucketList = new ArrayList<>(10);
        for (int i = 0; i < 10; i++) {
            bucketList.add(new LinkedList<>());
        }

        //找出資料中最大值
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (max < arr[i]) {
                max = arr[i];
            }
        }

        //獲取最大值的位數
        int maxRadix = (max + "").length();
        //從個位開始
        for (int i = 0; i < maxRadix; i++) {
            //將待排序元素放入桶中
            for (int j = 0; j < arr.length; j++) {
                //獲取數字對應位上的值
                int radix = arr[j] / (int) Math.pow(10, i) % 10;
                //放入對應的桶中
                bucketList.get(radix).add(arr[j]);
            }
            //將桶中元素放回原陣列
            int k = 0;
            for (int j = 0; j < 10; j++) {
                for (Integer number : bucketList.get(j)) {
                    arr[k++] = number;
                }
                bucketList.get(j).clear();
            }
        }
        return arr;
    }
}

另:排序演算法的穩定性

1. 穩定性的定義
假定在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些記錄的相對次序保持不變,即在原序列中,ri=rj,且ri在rj之前,而在排序後的序列中,ri仍在rj之前,則稱這種排序演算法是穩定的;否則稱為不穩定的。

舉個栗子:以{6,2,4,6,1}為例

a[0] a[1] a[2] a[3] a[4]
6 2 4 6 1

有兩個6,a[0]和a[3]。排序結果就有兩種可能:

1 2 4 6 6
原a[4] 原a[1] 原a[2] 原a[0] 原a[3]
原a[4] 原a[1] 原a[2] 原a[3] 原a[0]

如果排序結束後,a[0]可以保證一定在a[3]前頭,也就是他們原有的順序不變,那這種排序演算法就是穩定的。反之,如果不能保證原有順序,這種演算法就是不穩定的

2. 常見演算法的穩定性
堆排序、快速排序、希爾排序、直接選擇排序不是穩定的排序演算法,而基數排序、氣泡排序、直接插入排序、折半插入排序、歸併排序是穩定的排序演算法。

3. 穩定性的意義
1、如果只是簡單的進行數字的排序,那麼穩定性將毫無意義。
2、如果排序的內容僅僅是一個複雜物件的某一個數字屬性,那麼穩定性依舊將毫無意義(所謂的交換操作的開銷已經算在演算法的開銷內了,如果嫌棄這種開銷,不如換演算法好了?)
3、如果要排序的內容是一個複雜物件的多個數字屬性,但是其原本的初始順序毫無意義,那麼穩定性依舊將毫無意義。
4、除非要排序的內容是一個複雜物件的多個數字屬性,且其原本的初始順序存在意義,那麼我們需要在二次排序的基礎上保持原有排序的意義,才需要使用到穩定性的演算法。例如要排序的內容是一組原本按照價格高低排序的物件,如今需要按照銷量高低排序,使用穩定性演算法,可以使得想同銷量的物件依舊保持著價格高低的排序展現,只有銷量不同的才會重新排序。(當然,如果需求不需要保持初始的排序意義,那麼使用穩定性演算法依舊將毫無意義)。

參考:

https://www.cnblogs.com/songjilong/p/12234856.html

https://blog.csdn.net/sunxianghuang/article/details/51872360

https://blog.csdn.net/it_zjyang/article/details/53406764

https://www.cnblogs.com/hydor/p/3530593.html

https://blog.csdn.net/chenliguan/article/details/53037482