冒泡排序: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²),可是比冒泡算法大約快一倍左右,比選擇排序稍快,尤爲是部分數據局部有序的狀況下,插入法排序效率會更高