冒泡排序、選擇排序、遞歸排序跟快速排序

 

排序算法,基本的高級語言都有一些提供。C語言有qsort()函數,C++有sort()函數,java語言有Arrays類(不是Array)。用這些排序時,都可以寫自己的排序規則。

Java API對Arrays類的說明是:此類包含用來操作數組(比如排序和搜索)的各種方法。

 

上面兩句話話是對其他博客上的引用,不清楚是那篇了,所以就不貼地址了,其實除了數組,java對集合也有sort()的排序方法,這裏詳細寫一下對數組的幾種常用的排序方法。

 

 

快速排序是對選擇排序和冒泡排序的優化

 

選擇排序我覺得是最好理解的,冒泡排序推薦看下:https://www.cnblogs.com/shen-hua/p/5422676.html,寫的很清楚

 

冒泡排序:

 

    @Test
    public void test4() {
        int a[] = {49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 56, 17, 18, 23, 34, 15, 35, 25, 53, 51};
        for(int i=0;i<a.length-1;i++) {
            for (int j = 0; j < a.length - 1-i; j++) {
                if (a[j] > a[j + 1]) {
                    int t = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = t;
                }

            }
        }
        System.out.println(Arrays.toString(a));
    }

 

 

 

 

 

 

選擇排序:

    @Test
    public void test2() {
        int a[] = {49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 56, 17, 18, 23, 34, 15, 35, 25, 53, 51};
        for (int i = 0; i < a.length; i++) {
            for (int j = i + 1; j < a.length; j++) {
                if (a[i] > a[j]) {
                    a[j] = a[i] + a[j];
                    a[i] = a[j] - a[i];
                    a[j] = a[j] - a[i];
                }
            }
        }

 

遞歸排序:遞歸的本質---自身調用自身

 

# 求階乘
   
 public static void main(String[] args) {
        System.out.println(f(5));
        System.out.println(5 * 4 * 3 * 2 * 1);
    }

    public static int f(int n) {
        if (1 == n || 2 == n)
            return n;
        else
            return n * f(n - 1);
        /*
        * 5*f4
        * 5*4*f3
        * 5*4*3*f2
        * 5*4*3*2
        * */
    }

 

    /*
        斐波那契數列: 0、1、1、2、3、5、8
        f0 = 0; f1 = 1; fn = f(n-1) + f(n - 2) (n >= 2)
        
    */
    public static void main(String[] args) {
        System.out.println(f(5));
    }    
        public static int f(int n) {
            if (n == 1 || n == 2) {
                return 1;
            } else {
                return f(n - 1) + f(n - 2);
            }
        }

快速排序分治法就用到了遞歸思想,主要有挖坑法和下標交換法,分治也用到交換思想,

挖坑法

package study.test;

import java.util.Arrays;

public class Mysort {
    public static void quickSort(int[] arr, int startIndex, int endIndex) {
// 遞歸結束條件:startIndex大等於endIndex的時候(即每部分數組拆分至一個元素)
        if (startIndex >= endIndex) {
            return;
        }
// 得到基準元素位置
        int pivotIndex = partition(arr, startIndex, endIndex);
// 用分治法遞歸數列的兩部分
        quickSort(arr, startIndex, pivotIndex - 1);
        quickSort(arr, pivotIndex + 1, endIndex);
    }

    private static int partition(int[] arr, int startIndex, int endIndex) {
        System.out.println("the begin : " + Arrays.toString(arr));
// 取第一個位置的元素作爲基準元素
        int pivot = arr[startIndex];
        int left = startIndex;
        int right = endIndex;
// 坑的位置,初始等於pivot的位置
        int index = startIndex;
//大循環在左右指針重合或者交錯時結束
        while (right >= left) {
//right指針從右向左進行比較
            while (right >= left) {
                if (arr[right] < pivot) {
                    arr[left] = arr[right];
                    index = right;
                    left++;
                    break;
                }
                right--;
                System.out.println("the in one: " + Arrays.toString(arr));
            }
//left指針從左向右進行比較
            while (right >= left) {
                if (arr[left] > pivot) {
                    arr[right] = arr[left];
                    index = left;
                    right--;
                    break;
                }
                left++;
                System.out.println("the in two: " + Arrays.toString(arr));
            }
        }
        arr[index] = pivot;
        System.out.println("the end : " + Arrays.toString(arr));
        return index;
    }

    public static void main(String[] args) {
        int[] arr = new int[]{4, 7, 6, 5, 3, 2, 8, 1};
        quickSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
}

非交換思想,使用數組拆分

package study.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class JustSort {
    public static int partition(int[] arr, int start, int end) {
        int mid = start + (end - start) / 2;    //每次取中位數爲基準元素
        System.out.println("基準元素取中 mid :" + arr[mid]);
        List<Integer> left = new ArrayList();
        List<Integer> rigth = new ArrayList();
        for (int i = 0; i <= end; i++) {    //遍歷數組,使用集合分別存儲大於基準數和小於基準數的元素
            if (i != mid) {     //遍歷過錯中先隔離基準數,待遍歷完畢後存儲基準數,保證基準數在數組中下標不變
                if (arr[i] <= arr[mid]) {
                    left.add(arr[i]);
                }
                if (arr[i] > arr[mid]) {
                    rigth.add(arr[i]);
                }
            }
        }
        int index = left.size();    //獲取數組分治後下一輪數組的長度作爲下一次排序的範圍
        left.add(arr[mid]);     //添加基準數
        left.addAll(rigth);     //此時left集合中存儲當次排序後元素
        for (int i = 0; i < left.size(); i++) {
            arr[i] = left.get(i);       //將排序後元素從list更新到原數組
        }
        System.out.println(Arrays.toString(arr));
        return index;
    }

    public static void sort(int[] array, int start, int end) {
        if (start >= end) {     //當拆分數組元素僅有1個時,出現截取數組終止下標比開始下標小1或者相等(第一個元素時相等),此時無需排序
            return;
        }
        int mid = partition(array, start, end);
        sort(array, start, mid - 1);    //根據基準數切割數組,選取基準數左邊數組
        sort(array, mid + 1, end);      //選取基準數右邊數組
    }

    public static void main(String[] args) {
        int[] arr = {4, 7, 6, 5, 3, 2, 8, 1};
        System.out.println("源數組: \n" + Arrays.toString(arr));
        sort(arr, 0, arr.length - 1);
        System.out.println("排序結果: \n" + Arrays.toString(arr));
    }
}

 

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