簡單排序算法 冒泡排序 選擇排序 插入排序

冒泡排序:java

  整體思路:對未排序的各個元素,依次比較兩個元素,若是這兩個元素爲逆序(與想要的順序相反),則交換這兩個元素。算法

這樣能夠有兩種排序的思路:數組

思路一:性能

  固定位置排序:好比有一個未排序隊列,下標依次爲0,1,2,.....N-1,spa

      第一輪排序:首先固定位置0,將下標爲0的元素依次和下標爲一、下標爲二、....下標爲N-1的元素相比較,若相比較的兩個元素爲逆序,則交換這兩個元素,這樣第一輪排序完以後,位置爲0的元素,就是最大的(最小的)。code

  第二輪排序:首先固定位置1,將下標爲1的元素依次和下標爲二、下標爲三、....下標爲N-1的元素相比較,若相比較的兩個元素爲逆序,則交換這兩個元素,這樣第二輪排序完以後,位置爲1的元素,就是第二大的(第二小的)。blog

     ...排序

  第i輪排序(i<N-1):首先固定位置i,將下標爲i的元素依次和下標爲i+一、下標爲i+二、....下標爲N-1的元素相比較,若相比較的兩個元素爲逆序,則交換這兩個元素,這樣第i輪排序完以後,位置爲i的元素,就是第i+1大的(第i+1小的)。隊列

  第N-1輪排序:首先固定位置N-2,將下標爲N-2的元素和下標爲N-1的元素相比較,若相比較的兩個元素爲逆序,則交換這兩個元素,這樣第N-1輪排序完以後,位置爲N-2的元素,就是第N-1大的(第N-1小的)。class

     這樣通過N-1輪排序以後,各個位置的元素都是已經排好序了的。

     固定位置排序代碼演示以下:

  

import java.util.Arrays;
public class BubboleSort {
    public static void main(String[] args) {
        BubboleSort bs = new BubboleSort();
        int[] array = {2,5,1,3,9,8,0,4,6};
        System.out.println(Arrays.toString(array));
        bs.bubbleSort(array);
        System.out.println(Arrays.toString(array));
    }

    public void bubbleSort(int[] array){
        //外層取出一個用來比較的位置,當位置i肯定以後,內層循環進行完以後,該位置的元素就肯定了
        for (int i = 0; i < array.length; i++) {
            //內層循環依次取出須要進行比較的數據
            for (int j = i+1; j < array.length; j++) {
                if (array[i] > array[j]) {
                    swap(array,i,j);
                }
            }
        }
    }
   //交換數組中位置i和位置j的元素
    public void swap(int[] array,int i,int j){
        array[i] = array[i]^array[j];
        array[j] = array[i]^array[j];
        array[i] = array[i]^array[j];
    }
}

控制檯輸出:

[2, 5, 1, 3, 9, 8, 0, 4, 6]
[0, 1, 2, 3, 4, 5, 6, 8, 9]

思路二:

  相鄰元素比較:將相鄰的兩個元素依次進行比較,若是這兩個元素逆序,則進行交換。好比有一個未排序隊列,下標依次爲0,1,2,.....N-1,

  第一輪排序:

    將下標爲0的元素和下標爲1的元素進行比較,若逆序,則交換;

       再將下標爲1的元素和下標爲2的元素進行比較,若逆序,則交換;

    再將下標爲2的元素和下標爲3的元素進行比較,若逆序,則交換;

    ...

    將下標爲i(i<N-2)的元素和下標爲i+1的元素進行比較,若逆序,則交換;

    最後將下標爲N-2的元素和下標爲N-1的元素進行比較,若逆序,則交換。

  這樣,通過第一輪排序以後,最大(最小)的元素,就排在最後面了(下標爲N-1),即隊列最後的元素是排好序的,下一輪排序不用再排序了。

    第二輪排序:

    將下標爲0的元素和下標爲1的元素進行比較,若逆序,則交換;

       再將下標爲1的元素和下標爲2的元素進行比較,若逆序,則交換;

    再將下標爲2的元素和下標爲3的元素進行比較,若逆序,則交換;

    ...

    將下標爲i(i<N-3)的元素和下標爲i+1的元素進行比較,若逆序,則交換;

    最後將下標爲N-3的元素和下標爲N-2的元素進行比較,若逆序,則交換。

  這樣,通過第二輪排序以後,最二大(最二小)的元素,就排在最後面了(下標爲N-2),即下標爲N-2的元素是排好序的,下一輪排序不用再排序了。

     重複上面的排序思路便可將剩餘的元素所有排好順序。

代碼演示以下:

import java.util.Arrays;
public class BubboleSort {
    public static void main(String[] args) {
        BubboleSort bs = new BubboleSort();
        int[] array = {2,5,1,3,9,8,0,4,6};
        System.out.println(Arrays.toString(array));
        bs.bubbleSort(array);
        System.out.println(Arrays.toString(array));

    }
 //相鄰元素進行比較排序
    public void bubbleSort(int[] array){
        //i用來控制比較的次數
        for (int i = array.length -1; i > 0 ; i--) {
            //內層循環完成以後,表示一輪冒泡完成
            for (int j = 0; j < i; j++) {
                if (array[j] > array[j+1]) {
                    swap(array,j,j+1);
                }
            }
        }
    }
 //交換數組中位置i和位置j的元素
    public void swap(int[] array,int i,int j){
        array[i] = array[i]^array[j];
        array[j] = array[i]^array[j];
        array[i] = array[i]^array[j];
    }
   
}

 控制檯輸出:

[2, 5, 1, 3, 9, 8, 0, 4, 6]
[0, 1, 2, 3, 4, 5, 6, 8, 9]

冒泡排序性能:比較和交換的次數爲 O(n2)

 

選擇排序:

  假設有一個待排序的數組array,下標依次爲0,1,2,3,....N-1

  第一輪排序:從全部元素中選擇一個最小(最大)值array[i],放在array[0]位置(即讓array[i]與array[0]交換)。

  第二輪排序:從array[1]開始,找出一個最小(最大)值array[j],放在array[1]位置。

  ...

  N個數,要進行N-1輪排序。

  下面是代碼演示:

import java.util.Arrays;

public class SelectSort {
    public static void main(String[] args) {
        SelectSort ss = new SelectSort();
        int[] array = {2,5,1,3,9,8,0,4,6};
        System.out.println(Arrays.toString(array));
        ss.selectSort(array);
        System.out.println(Arrays.toString(array));
    }
    public void selectSort(int[] array){
        for (int i = 0; i < array.length; i++) {
            int minIndex = i;
            for (int j = i+1; j < array.length; j++) {
                //只記錄位置,暫時不交換
                if (array[minIndex] > array[j]) {
                    minIndex = j;
                }
            }
            //通過內層循環以後,找到了該輪外層循環的位置i的要交換的最小值的位置minIndex,交換,若i== minIndex,說明位置i所在的元素,就是該輪比較的最小值了,因此不用交換了
            if (i != minIndex) {
                swap(array,i,minIndex);
            }
        }
    }

    public void swap(int[] array,int i,int j){
        array[i] = array[i]^array[j];
        array[j] = array[i]^array[j];
        array[i] = array[i]^array[j];
    }
}

控制檯輸出:

[2, 5, 1, 3, 9, 8, 0, 4, 6]
[0, 1, 2, 3, 4, 5, 6, 8, 9]

選擇排序效率:比較次數爲O(n²),交換的次數爲O(n)

 插入法排序:

基本思路:(設數組爲升序) 每拿到一個元素,都要將這個元素依次與它以前的元素進行比較,若前面的元素比該元素大,則將前面的元素日後移動;直到前面的元素(設下標爲i)比該元素小,則下標爲i+1,就是該元素要插入的位置,插入便可
代碼演示以下:
package com.lewis.sort.simpleSort;


import java.util.Arrays;

public class InsertSort {
    public static void main(String[] args) {
        InsertSort is = new InsertSort();
        int[] array = {2, 5, 1, 3, 0,9,-1, 8, 7, 4, 6};
        System.out.println(Arrays.toString(array));
        is.sort(array);
        System.out.println(Arrays.toString(array));
    }

    /**
     * 插入法排序:經過構建有序數列,將未排序的元素,從後往前依次比較,進而找到要插入的位置並插入
     * @param array
     */
    public void sort(int[] array){
        int j = 0;
        //假設數組中的第一個元素是已經排好序的
        //外層循環 表示待排序的元素
        for (int i = 1; i < array.length; i++) {
            //待排序的元素tmpData,要找到一個合適的位置插入
            int tmpData = array[i];
            //內層循環從待排序元素tmpData開始,依次往前掃描
            for (j = i; j > 0 ; j--) {
                //將待排序元素tmpData依次和前面的元素比較, 若前面的元素比待排序的元素tmpData大,則將前面的元素依次日後移動
                if (array[j - 1] > tmpData) {
                    array[j] = array[j-1];
                }
                else{
                    //說明前面已是排好順序了
                    break;
                }
            }
            //內層循環結束以後,位置j就是待排序元素要插入的位置
            array[j] = tmpData;
        }
    }

}

控制檯輸出:

[2, 5, 1, 3, 0, 9, -1, 8, 7, 4, 6]
[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

插入法排序效率:比較和交換次數都爲 O(n²),可是比冒泡算法大約快一倍左右,比選擇排序稍快,尤爲是部分數據局部有序的狀況下,插入法排序效率會更高

相關文章
相關標籤/搜索