Java排序演算法之氣泡排序 插入排序 選擇排序

2021-09-23 17:02:17 字數 3660 閱讀 3387

一、前言

排序是日常中最常見的一種演算法,常見的演算法有:氣泡排序、插入排序、選擇排序、歸併排序、快速排序、計數排序、快速排序、基數排序、桶排序。那麼該怎樣分析和學習排序演算法呢?

二、演算法的分析課

在上述的八種排序方法中,根據時間複雜度和是否基於比較可以為三種:

排序演算法

時間複雜度

是否基於比較

冒泡、插入、選擇

o(n2)

是歸併、快排

o(nlogn)

是桶、基數、計數

o(n)

否在學習演算法的實現原理和實現方法時,還應掌握哪些技能呢?

1)、排序演算法的執行效率:排序演算法的執行執行效率主要從時間複雜度和時間複雜度的係數、常階、低階;比較次數和交換次數三個方面來體現。

時間複雜度:主要包括最好情況時間複雜度,最壞情況時間複雜度和平均情況時間複雜度三種情況來分析

時間複雜度的係數、常階、低階:時間複雜度時表示資料規模為n很大的時候的乙個增長趨勢,所以係數、常階、低階都會忽略,不過在開發過程中,一般資料規模是已知的,這時候係數、常階、低階的影響是應該考慮進來的。

比較次數和交換次數:在排序過程中,一般會涉及比較和交換兩種操作,而了解演算法的比較次數和交換次數也是學習排序演算法的乙個重要指標。

2)排序演算法的記憶體消耗:在了解完排序演算法的執行效率後,效能消耗也是演算法的乙個重要的考量指標。而記憶體消耗的乙個重要體現就是空間複雜度。原地排序就是特指空間複雜度的為o(1)的排序演算法。

3)排序演算法的穩定性:穩定性是指在待排序的元素中存在相同的元素,經過排序後,相等元素之間原有的先後順序不變。

三、氣泡排序:

實現原理:氣泡排序只會操作相鄰的兩個元素,每次冒泡只會比較兩個相鄰元素的大小。根據大小關係要求,如果不滿足大小要求,就讓兩個元素互換,也就是一次冒泡。一次冒泡至少會讓乙個元素移動,一直重複n次,直到完成排序。

**實現:

//正序排序:讓陣列的每乙個元素與相鄰的對比,如果滿足條件,則兩個資料交換,依次直到排序完成。每次冒泡都會把最大的值放到最後,完成冒泡的值不需要在進行排序。

int a = ;

for (int j = 0; j < a.length; j++)

} if (!flag)

} for (int k = 0; k < a.length; k++)

}//倒序排序:與正序排序相同,只是遍歷的過程和比較條件相反。

int a = ;

for (int j = a.length; j >= 0; j--)

} if (!flag)

} for (int k = 0; k < a.length; k++)

我們可以從三個方面來分析冒泡演算法:

1、 排序演算法的執行效率:最好情況只進行一次冒泡時間複雜度為o(n),最壞情況是元素與要排序的方向完全相反,時間複雜度為o(n2)。平均時間複雜度可以用有序度和無序度來分析。有序度指定的要比較的兩個元素與要排序的順序相同,如陣列a中(1,3)就是乙個有序度,預設從小到大為有序。當乙個完全排序的陣列,它的有序度為n*(n-1)/2,稱之為滿有序度。而與有序相反的也就是逆序度, 逆序度=滿有序度-有序度。排序的過程就是增加有序度,減少逆序度的過程,達到滿有序度,排序也就完成了。滿有序度-初始有序度就等於逆序度也就是資料交換的次數,例子中等於10-2=8。平均時間複雜度取個中間值也就是n*(n-1)/4,也就是o(n2)。

2、演算法的效能消耗:從**中,我們可以看出氣泡排序只涉及相鄰資料的交換操作,所以空間複雜度為o(1),也就是說氣泡排序是乙個原地排序演算法。

3、穩定性:冒泡排只有在兩個元素滿足比較條件是才會進行交換,兩個相同的元素不會進行交換,所以氣泡排序是乙個穩定的排序演算法。

四、插入排序:

實現原理:在有序陣列中插入乙個元素,如何保證元素的順序?其實很簡單,只要遍歷整個陣列,找到資料應該插入的位置將元素插入即可。插入排序演算法正式借助上面的思路。首先,將陣列分為兩個區域,已排序區域和未排序區域。初始的已排序區域只有乙個元素,也就是陣列的第乙個元素。而插入演算法的核心思想就是取未排序的區域的元素,在已排序的區域中找到合適的位置將元素插入,並且保證已排序區域一直有序。重複這個過程,直到排序結束。

**實現:

//正序排序

int a=;

for (int i = 0; i < a.length; i++) else

} a[j+1]=temp;

} for (int i = 0; i < a.length; i++)

//逆襲排序

int a=;

for (int i = 0; i < a.length; i++) else

} a[j+1]=temp;

} for (int i = 0; i < a.length; i++)

}

演算法分析(正向排序):

插入排序也涉及兩個動作:比較和移動。其實實質也是相鄰兩個元素間的移動,並不會產生額外的儲存空間,所以插入排序的空間複雜度是o(1),是乙個原地排序演算法。

插入排序中,如果有相同的元素,我們可以選擇後面出現的元素,插入到前面出現元素的後面,這樣就可以保持原有的前後順序不變,從而插入排序是穩定的排序演算法。

插入排序的時間複雜度,及時是乙個已經排序的陣列,它執行的時間複雜度也是o(n),如果是乙個逆序排序的陣列,那麼正序排序的時間複雜度就是o(n2)。而平均時間複雜度也是o(n2),因為每次插入的操作都相當於在陣列中插入乙個元素,執行n次結束。還可以根據有序度來得到陣列元素移動的次數是:8次。

五、選擇排序:

實現原理:選擇排序的實現原理與插入排序型別,也是分為已排序區域和未排序區域。不過選擇排序是每次從未排序中選擇最小的元素找到最小的元素,將其放到已排序區域的末尾,直到排序完成。

**實現:

int  a=;

for (int i = 0; i < a.length; i++)

} //獲取最小值

int temp=a[min];

//將已排區域的值放置到最小值的位置

a[min]=a[i];

//將最小值放到已經排序區域末尾

a[i]=temp;}

for (int i = 0; i < a.length; i++)

}

效能消耗:選擇排序的空間複雜度為o(1),是一種原地排序演算法。

穩定性:選擇排序不是一種穩定的排序演算法,每次排序時都會選擇剩餘元素中最小的值,並和前面的元素交換位置,相同數值的元素位置也會變化,這樣就是破壞了穩定性。比如6,3,2,6,5,在找到最小值時,2會和第1個6交換位置,那麼6和6之位置也發生了變化。

時間複雜度:從**中可以看出,無論是最好還是最壞情況,選擇的排序的時間複雜度都為o(n2)。

以上就是三種比較常見的排序演算法,下面用圖表來做下總結:

排序演算法

時間複雜度(最好,最壞,平均)

空間複雜度

原地演算法

穩定性氣泡排序

o(n),o(n2),o(n2)

o(1)是是

插入排序

o(n),o(n2),o(n2)

o(1)是是

選擇排序

o(n2),o(n2),o(n2)

o(1)是否

java 排序演算法之氣泡排序

氣泡排序是一種最基礎也是最簡單的排序演算法,它是一種穩定排序演算法,其平均時間複雜度為o n2 on2 空間複雜度為o 1 o1 是一種原地排序演算法。氣泡排序的思想其實很簡單,就是從最後乙個元素開始,依次與其前面的元素作比較,如果位置錯誤就交換位置,否則不採取操作,一直到第乙個元素,此時第乙個元素...

Java排序演算法之氣泡排序

package demosort 在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即 每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。public class bubblesort int temp 0...

Java排序演算法之氣泡排序

1.比較相鄰的元素。如果第乙個比第二個大,就交換他們兩個。2.對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。3.針對所有的元素重複以上的步驟,除了最後乙個。4.持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。public cl...