1. 程式人生 > >常用算法(Java表述)

常用算法(Java表述)

select 進入 關鍵字 tostring ima oid 掃描 初始化 sele

冒泡排序(Bubble Sort):一種交換排序,它的基本思想是:兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。穩定排序算法

時間復雜度 O(n2),裏層循環每趟比較第 j 項和第 j+1項,如果前項大於後項,則發生交換。缺點是每次比較後都可能發生交換,交換次數太多了,值從小到大。

技術分享圖片

通俗概述:依次比較相鄰兩關鍵字,如果反序則立即發生交換,如果正序則繼續比較下一個相鄰項,雙重嵌套循環實現

參考代碼:

package com.tyut;

import java.util.Arrays;

/**
 * 冒泡排序:利用雙重循環,如果前一個數比後一個數大,則發生交換,每次比較都發生交換
   優化版:添加flag標記,循環外定義flag標記為true,進入循環後flag設為false,
  若一次循環後發生了交換則將flag設為ture,進入下次循環;若整次循環只發生比較未發生交換,則說明數組已經有序,後續循環比較則不必要了,減少比較次數,提升性能
*/ public class BubbleSort { public static void bubbleSort(int[] arrs) { int temp = 0;      boolean flag=true;//用flag作標記,當沒有發生交換的時候,說明數組已經是有序的了。 for (int i = 0; i < arrs.length - 1&&flag; i++) {      flag
=false;//flag標記初始化為false; for (int j = 0; j < arrs.length - i - 1; j++) { //判斷當前項是否大於後一項 if (arrs[j] > arrs[j + 1]) {//是,則發生交換 temp = arrs[j]; arrs[j] = arrs[j + 1]; arrs[j + 1] = temp; flag
=true;//發生交換flag標記設為true } } } } public static void main(String[] args) { int[] arr=new int[]{2,6,5,4,2,4,6,9,7}; System.out.println(Arrays.toString(arr)); bubbleSort(arr); System.out.println(Arrays.toString(arr)); } }

選擇排序有:簡單選擇排序、樹形選擇排序、堆排序

簡單選擇排序(Simple Selection Sort):就是通過n-1次關鍵字間的比較,從n-i+1個記錄中選出關鍵字最小的記錄,並和i(1<=i<=n)個記錄交換值

時間復雜度 O(n2),在冒泡排序的基礎上,只不過每次比較後,將保存最小值的索引指向小值,在一次循環結束時,將最小值與循環首項發生交換。整體分為已排序和未排序兩部分,值從小到大。

技術分享圖片

註意區別:冒泡排序跟直接選擇排序都是依次比較相鄰的記錄,但是冒泡排序是一有反序立即交換,而直接插入排序則是出現反序將最小值記錄下來,最後再發生交換。

參考代碼:

package com.tyut;

import java.util.Arrays;

/**
 * 簡單選擇排序:在待排序中找出最小值,然後放到已排序的末尾
 *          利用雙重for循環,找出最小值,再發生一次交換
 */
public class SelectionSort {
    //需要遍歷獲得最小值的次數
    //要註意一點,當要排序N個數,已經經過N-1次遍歷後,已經是有序數列
    public static void selectSort(int[] arrs) {
        for (int i = 0; i < arrs.length - 1; i++) {
            int temp=0;
            int index=i;//用來保存最小的索引,初始指向當前第i項
            //從未排序數中找出最小值,這裏最大索引應該是數組最後一位即length-1
            for (int j = i+1; j <arrs.length; j++) {
                //如果後面的值比索引值還小,則將索引指向最小值
                if (arrs[j]<arrs[index]){
                    index=j;
                }
            }
            //已經找到最小值,然後將最小值放到已排序的末尾
            temp=arrs[i];
            arrs[i]=arrs[index];
            arrs[index]=temp;
        }
    }

    public static void main(String[] args) {
        int[] arrs=new int[]{2,6,8,99,4,46,4,5};
        System.out.println(Arrays.toString(arrs));
        selectSort(arrs);
        System.out.println(Arrays.toString(arrs));
    }
}

直接插入排序( Straight Insertion Sort):是將一個記錄插入到已經排好序的有序表中,從而得到一個新的、記錄增1的有序表。是一種最簡單的插入排序,穩定算法

時間復雜度O(n2),利用雙重for循環,從第二個數開始遍歷,然後保存待插入的數,這樣有序部分則可以向後覆蓋一個位置,然後裏層循環 j >= 0 && temp < arrs[j] 找到合適的位置後,只需要將待插入的數插入即可。

技術分享圖片

參考代碼:

package com.tyut;

import java.util.Arrays;

/**
 * 插入排序:
 */
public class InsertionSort {
    public static void insertSort(int[] arrs) {
        //第一個肯定是有序的,所以從第二個數開始遍歷
        for (int i = 1 ;i < arrs.length - 1; i++) {
            int j=0;
            int temp = arrs[i];//取出第i給數,和前i-1個數比較,插入合適位置。
            //因為前i-1個數都是從小到大的有序序列,所以只要當前比較的數arr[j]比temp大,就把這個數後移一位
            for (j = i - 1; j >= 0 && temp < arrs[j]; j--) {
                arrs[j+1]=arrs[j];//因為第i個數已經保存為temp,所以可以向後覆蓋
            }
            //將第i個值插入到合適位置,因為交換結束後再自減運算,所以這裏需要+1
            arrs[j+1]=temp;
        }
    }
    public static void main(String[] args) {
        int[] arrs=new int[]{2,6,5,2,3,4,3,0,6};
        System.out.println(Arrays.toString(arrs));
        insertSort(arrs);
        System.out.println(Arrays.toString(arrs));
    }
}

希爾排序(Shell Sort)又稱為增量排序,它是一種插入排序,它是直接插入排序算法的一種威力加強版。它的基本思想是:把記錄按步長 gap(差距,間隙) 分組,對每組記錄采用直接插入排序方法進行排序。 隨著步長逐漸減小,所分成的組包含的記錄越來越多,當步長的值減小到 1 時,整個數據合成為一組,構成一組有序記錄,則完成排序。

時間復雜度為O(nlogn),該方法因DL.Shell於1959年提出而得名。超越了O(n2)的算法的歷史。他是在直接插入排序的增強,將記錄按步長gap分組,然後在分組內進行直接插入排序。不穩定算法。

技術分享圖片

參考代碼:

package com.tyut;

import java.util.Arrays;

/**
 * 希爾排序:在直接插入排序的基礎上,將記錄按步長進行分組
 *          所以可知,直接插入排序相當與步長為1的希爾排序
 */
public class ShellSort {
    public static void shellSort(int[] arrs) {
        //初始化步長為數組長度的一半
        int gap = arrs.length / 2;
        //循環結束條件,當gap<1是,循環結束,即排序結束
        while (gap >= 1) {
            //把距離為gap的元素編為一個組,掃描所有組
            for (int i = gap; i < arrs.length; i++) {
                int j = 0;
                int temp = arrs[i];//保存待插入元素,以便組內元素向後移動覆蓋
                //對距離為gap的組內元素進行直接選擇排序
                for (j = i - gap; j >= 0 && temp < arrs[j]; j = j - gap) {
                    arrs[j+gap]=arrs[j];
                }
                //將待插入元素插入合適位置
                arrs[j+gap]=temp;
            }
            //一次循環結束,所有分組均已完成直接選擇排序,則可將將距離縮小為原本的一半
            gap=gap/2;
        }
    }

    public static void main(String[] args) {
        int[] arrs=new int[]{3,6,8,4,6,7,9,8,7,5};
        System.out.println(Arrays.toString(arrs));
        shellSort(arrs);
        System.out.println(Arrays.toString(arrs));
    }
}

![](D:\百度雲\Resource\img_algotirhm\Shell-Sort.png)

常用算法(Java表述)