Java 簡單排序__Java

來源:互聯網
上載者:User

一、冒泡排序


如圖所示,如果有五個元素需要排序,那麼需要排n-1趟,那麼我們是不是可以寫出一個迴圈出來,

for(int i = 1; i <= size-1; i++)
但是我們發現每一趟的比較次數隨著趟數的增大而減小,所以我們是不是可以 修改一下迴圈呢

for(int i = size-1; i > 0; i--)
這樣不就成了隨著趟數的增大i在減小嗎,現在我們算是寫出了演算法的框框了,我們還要比較元素,有圖上分析可知,比較次數在逐趟減小,並且都是從下標為0開始比較的,於是,還需要一個迴圈來比較元素

for(int j =0; j < ?; j++)

此時,問題來了,臨界值是什麼,“。”是幾呢,再分析一下,第一趟比較下標從0到4,第二趟比較下標從0到3發現小標的變化和i是一樣的,並且可以等於i,於是修改迴圈

for(int j =0; j <= i; j++)
此時感覺很對了,但是仔細想想,這個for迴圈的內容是什麼呢,應該是source[j] 和source[j+1]進行比較,然後交換,如果j可以等於i,那麼j+1不就比i還大麼,所以我們應該把等號去掉,變為
for(int j =0; j < i; j++)
為了使取名有意義,可以修改一下這兩個迴圈

for(int outer = size - 1; outer > 0; outer--){    for(int inner = 0; inner < outer; inner++)    {//比較邏輯        int temp = source[inner + 1];        source[inner + 1] = array[inner];        source[inner] = temp;    }}
完整程式如下所示:

package com.darren.test.sort;public class BubbleSortTest {    public static void main(String[] args) {        int[] array = new int[] { 3, 5, 9, 8, 6, 4, 3, 1, 8, 7 };                System.out.print("before sort:");        print(array);        System.out.println();                int size = array.length;        for (int outer = size - 1; outer >= 0; outer--) {            for (int inner = 0; inner < outer; inner++) {                if (array[inner] > array[inner + 1]) {                    int temp = array[inner + 1];                    array[inner + 1] = array[inner];                    array[inner] = temp;                }            }        }                System.out.print("after sort:");        print(array);    }    private static void print(int[] source) {        for (Integer data : source) {            System.out.print(data);            System.out.print(", ");        }    }}


二、插入排序


如圖所示,如果有五個元素需要排序,那麼需要排n-1趟,並且下標是從1到n-1,那麼我們是不是可以寫出一個迴圈出來

for(int i = 1; i < size; i++)
由圖可知,我們每次都是把source[i]插入到左邊,那麼是不是應該把source[i]臨時儲存一下呢,我想是應該的

int temp = source[i];
那麼演算法內部是如何進行比較插入的呢,接下來進行分析,我們發現一直向左邊插入,其實左邊的序列一直是有序的,那麼我們就會從右向左比較插入就行了,所以第二個for迴圈是倒著的
for(int j = ?; j >=0; j--)
從圖上可知j可以為0,那麼最大可以是多少呢,再分析一下,最大比i小1,所以修改for迴圈
for(int j = i - 1; j >=0; j--)
怎麼比較呢
source[j] 和 source[j+1]進行比較。此時source[j+1]剛好等於source[i],因為j + 1 = i;

把變數取得有意義一點,結果為

for(int outer = 1; outer < size; outer++){    int sentinel = source[i];    for(int inner = outer - 1; inner >= 0; inner--)    {        if(source[inner] > source[inner + 1])        {            source[inner + 1] = source[inner];            source[inner] = sentinel;        }    }}
完整程式如下所示:

package com.darren.test.sort;public class InsertSortTest {    public static void main(String[] args) {        int[] array = new int[] { 3, 5, 9, 8, 6, 4, 3, 1, 8, 7 };                System.out.print("before sort:");        print(array);        System.out.println();                int size = array.length;        for (int i = 1; i < size; i++) {            int sentinel = array[i];            for (int j = i - 1; sentinel < array[j]; j--) {                array[j + 1] = array[j];                array[j] = sentinel;                if (j == 0) {                    break;                }            }        }                System.out.print("after sort:");        print(array);    }    private static void print(int[] source) {        for (Integer data : source) {            System.out.print(data);            System.out.print(", ");        }    }}

三、選擇排序






如圖所示,如果有五個元素需要排序,宏觀上看需要排n-1趟,並且下標是從0到n-2(注意黑色底線的起始位置),那麼我們是不是可以寫出一個迴圈出來

for(int i = 0; i < size - 1; i++)
第一個for迴圈並不關心具體是怎麼選出一個最小的放左邊的,只是先找到下標的變化規律,接著我們看內部是如何?選出最小值放左邊的,這個實現相對插入排序有所不同,只用圈圈不易表達,所以我們用一個具體例子來看。
對一個五個元素的數組進行排序:3 1 5 2 4

要比較,必須有一個參照物,我們假設每一趟中最左邊元素(黑色底線對應的最左邊元素)為參照物(int minValueIndex = i),然後拿之後的一個元素(int j = i + 1)和它比較,如果比它小,那麼就改變參照物,把新的最小的元素作為參照物,繼續拿它之後的元素與之比較,直到本趟結束,因為要拿j和左邊的元素比較而沒有j + 1,所以j可取到n-1

for(int j = i + 1; j < size; j++)
這裡有兩個問題
1.選個元素作為參照物還是元素的下標。
2.每一趟比較完應該做些什麼。

我們先回答第二個問題,每一趟比較完我們應該把最小的元素放到左邊的位置上,需要進行一次元素交換

然後回答第一個問題,我們知道要進行元素交換,如果使用元素作為參照物,那麼我只知道最小值是幾,卻不能和其他元素交換,因為我不知道最小值的下標,但是如果我們知道了最小值的下標,就能知道最小值,所以我們選用下標作為參照物

for(int outer = 0; outer < size - 1; outer++){    // 設定參照物為最左邊元素    int min = outer;    for(int inner = outer + 1; inner < size; inner++)    {        if(source[inner] < source[min])        {            // 更新參照物            min = inner;        }    }    // 交換最小值和最左邊值    int temp = source[outer];    source[outer] = source[min];    source[min] = temp;}


完整程式如下所示:

package com.darren.test.sort;public class SelectSortTest {    public static void main(String[] args) {        int[] array = new int[] { 3, 5, 9, 8, 6, 4, 3, 1, 8, 7 };                System.out.print("before sort:");        print(array);        System.out.println();                int size = array.length;        for (int outer = 0; outer < size - 1; outer++) {            int min = outer;            for (int inner = outer + 1; inner < size; inner++) {                if (array[inner] < array[min]) {                    min = inner;                }            }            int temp = array[outer];            array[outer] = array[min];            array[min] = temp;        }                System.out.print("after sort:");        print(array);    }    private static void print(int[] source) {        for (Integer data : source) {            System.out.print(data);            System.out.print(", ");        }    }}

總結:

幾種簡單排序演算法的比較
        一般情況下不使用冒泡排序,它過於簡單了,以至於可以毫不費力的寫出來,當資料很小的時候會有些使用價值。
        選擇排序雖然把交換次數降到最低,但比較次數仍然很大,當資料量很小,並且交換資料相對於比較資料更耗時的情況下可是使用選擇排序。
        大多數情況系,假設資料量比較小或基本有序時,插入排序演算法是三種簡單演算法最好的選擇,對於更大資料量來說,快速排序更好,以後會講快速排序演算法。


除了在速度方面比較演算法外,還有一種對演算法的衡量標準是演算法需要的記憶體空間有多大。這三種簡單演算法除了初始的數組外幾乎不需要其他記憶體空間。所有排序演算法都
需要一個額外的變數來儲存交換時的資料項目。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.