Java輕松入門冒泡?選擇?插入?希爾?歸并排序算法
今天我們主要看一些簡(jiǎn)單的排序

常見的時(shí)間復(fù)雜度
?? 常數(shù)階Ο(1)
?? 對(duì)數(shù)階Ο(log2n)
?? 線性階Ο(n)
?? 線性對(duì)數(shù)階Ο(nlog2n)
?? 平方階Ο(n²)
?? 立方階Ο(n³)
?? K次方階Ο(n^k)
?? 指數(shù)階Ο(2^n)
常見的時(shí)間復(fù)雜度對(duì)應(yīng)圖

Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n²)<Ο(n³)<…<Ο(2^n) <Ο(n!)<O(n^n)
冒泡排序(Quicksort)
算法描述:
①. 比較相鄰的元素。如果第一個(gè)比第二個(gè)大,就交換他們兩個(gè)。
②. 對(duì)每一對(duì)相鄰元素作同樣的工作,從開始第一對(duì)到結(jié)尾的最后一對(duì)。這步做完后,最后的元素會(huì)是最大的數(shù)。
③. 針對(duì)所有的元素重復(fù)以上的步驟,除了最后一個(gè)。
④. 持續(xù)每次對(duì)越來(lái)越少的元素重復(fù)上面的步驟①~③,直到?jīng)]有任何一對(duì)數(shù)字需要比較。

為了直觀感受,在網(wǎng)上找個(gè)動(dòng)態(tài)的演示

代碼實(shí)現(xiàn):
當(dāng)數(shù)組中有n個(gè)元素時(shí),只需要進(jìn)行n-1輪比較,則整個(gè)數(shù)組就是有序的
public static void bubbleSort(int[] arr) {
// 進(jìn)行i輪比較
for (int i = 0; i < arr.length - 1; i++)
{
for (int j = 0; j < arr.length - 1 - i; j++) {
//后一位的值大于前一位的值進(jìn)行值交換
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
}
}
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
選擇排序(Quicksort)
算法描述:
選擇排序是一種簡(jiǎn)單直觀的排序算法。它的工作原理是:第一次從待排序的數(shù)據(jù)元素中選出最?。ɑ蜃畲螅┑囊粋€(gè)元素,存放在序列的起始位置,然后再?gòu)氖S嗟奈磁判蛟刂袑ふ业阶钚。ù螅┰?,繼續(xù)放在起始位置知道未排序元素個(gè)數(shù)為0。

代碼實(shí)現(xiàn):
public static void selectionSort(int[] a) {
//每當(dāng)完成一輪,將會(huì)找到最小值,一個(gè)i代表一輪
for (int i = 0; i < a.length; i++) {
int index = i;
//每一輪從i+1開始找,查找是否有比當(dāng)前值更小的值
for (int j = i + 1; j < a.length; j++) {
if (a[index] > a[j]) {
index = j;
}
}//如果index和i不相等說明,下標(biāo)交換過,也就是說找到更小的數(shù)值了
if (index != i) {
swap(a, index, i);
}
}
}
public static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
插入排序(insertSort)
算法描述:
插入排序也是一種常見的排序算法,插入排序的思想是:將初始數(shù)據(jù)分為有序部分和無(wú)序部分,每一步將一個(gè)無(wú)序部分的數(shù)據(jù)插入到前面已經(jīng)排好序的有序部分中,直到插完所有元素為止。 插入排序的步驟如下:每次從無(wú)序部分中取出一個(gè)元素,與有序部分中的元素從后向前依次進(jìn)行比較,并找到合適的位置,將該元素插到有序組當(dāng)中。 將數(shù)組分為2端,有序數(shù)組和無(wú)序數(shù)組,依次將無(wú)序數(shù)組中的值插入到無(wú)序數(shù)組中。
如圖,插入4的過程如下 將數(shù)組分為2端,有序數(shù)組和無(wú)序數(shù)組,依次將無(wú)序數(shù)組中的值插入到無(wú)序數(shù)組中。
如下圖3 6 7為有序數(shù)組,4 2為無(wú)序數(shù)組。依次將4,2插入到無(wú)序數(shù)組中即可
如圖,插入4的過程如下

代碼實(shí)現(xiàn):
public static void insertionSort(int[] a) {
for (int i = 1; i < a.length; i++) {
int temp = a[i];
int j;
// 查到合適的插入位置,插入即可
for (j = i - 1; j >= 0 && a[j] > temp; j--) {
a[j + 1] = a[j];
}
a[j + 1] = temp;
}
}
希爾排序 (ShellSort)
算法描述:
希爾排序是基于插入排序改進(jìn)后的算法。因?yàn)楫?dāng)數(shù)據(jù)移動(dòng)次數(shù)太多時(shí)會(huì)導(dǎo)致效率低下。所以我們可以先讓數(shù)組整體有序(剛開始移動(dòng)的幅度大一點(diǎn),后面再小一點(diǎn)),這樣移動(dòng)的次數(shù)就會(huì)降低,進(jìn)而提高效率

代碼實(shí)現(xiàn):
public static void shellSort(int[] a) {
for (int step = a.length / 2; step > 0; step /= 2) {
//接下來(lái)的過程類似于插入排序
for (int i = step; i < a.length; i++) {
int temp = a[i];
int j;
for (j = i - step; j >= 0 && a[j] > temp ; j -= step) {
a[j + step] = a[j];
}
a[j + step] = temp;
}
}
}
歸并排序(MergetSort)
算法描述:
1.申請(qǐng)空間,使其大小為兩個(gè)已經(jīng)排序序列之和,該空間用來(lái)存放合并后的序列;
2.設(shè)定兩個(gè)指針,最初位置分別為兩個(gè)已經(jīng)排序序列的起始位置;
3.比較兩個(gè)指針?biāo)赶虻脑?,選擇相對(duì)小的元素放入到合并空間,并移動(dòng)指針到下一位置;
4.重復(fù)步驟 3 直到某一指針達(dá)到序列尾;
將另一序列剩下的所有元素直接復(fù)制到合并序列尾。

方便理解,直接網(wǎng)上找圖

代碼實(shí)現(xiàn):
public static void mergeSort(int[] a, int left, int right) {
// 將數(shù)組分段成只有一個(gè)元素
if (left == right) {
return;
}
int mid = (left + right) / 2;
mergeSort(a, left, mid);//遞歸
mergeSort(a, mid + 1, right);
merge(a, left, mid, right);
}
public static void merge(int[] a, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
int i = left;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= right) {
if (a[i] < a[j]) {
temp[k++] = a[i++];
} else {
temp[k++] = a[j++];
}
}
// 復(fù)制左邊數(shù)組剩余的值
while (i <= mid) {
temp[k++] = a[i++];
}
// 復(fù)制右邊數(shù)組剩余的值
while (j <= right) {
temp[k++] = a[j++];
}
int index = 0;
//把temp全部復(fù)制給數(shù)組
while (left <= right) {
a[left++] = temp[index++];
}
}
快速排序(QuickSort)
算法描述:
- 快速排序的執(zhí)行流程主要分為如下三步
- 從數(shù)列中取出一個(gè)數(shù)作為基準(zhǔn)數(shù)
- 分區(qū),將比它大的數(shù)全放到它的右邊,小于或等于它的數(shù)全放到它的左邊
- 再對(duì)左右區(qū)間重復(fù)第二步,直到各區(qū)間只有一個(gè)數(shù)

代碼實(shí)現(xiàn):
public static void quickSort(int[] a, int left, int right) {
if (left >= right) {
return;
}
int index = sort(a, left, right);
//得到中間值index,然后一分為二,繼續(xù)分
quickSort(a, left, index - 1);
quickSort(a, index + 1, right);
}
public static int sort(int[] a, int left, int right) {
//以左邊的a[left]為基準(zhǔn)數(shù)
int key = a[left];
while (left < right) {
// 從right所指位置向前搜索找到第一個(gè)關(guān)鍵字小于key的記錄和key互相交換
while (left < right && a[right] >= key) {
right--;
}
a[left] = a[right];
// 從left所指位置向后搜索,找到第一個(gè)關(guān)鍵字大于key的記錄和key互相交換
while (left < right && a[left] <= key) {
left++;
}
a[right] = a[left];
}
// 放key值,此時(shí)left和right相同
a[left] = key;
return left;
}
到此這篇關(guān)于Java輕松入門冒泡 選擇 插入 希爾 歸并排序算法的文章就介紹到這了,更多相關(guān)Java 排序算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java利用三目運(yùn)算符比較三個(gè)數(shù)字的大小
今天小編就為大家分享一篇關(guān)于Java利用三目運(yùn)算符比較三個(gè)數(shù)字的大小,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12
學(xué)java得這樣學(xué),學(xué)習(xí)確實(shí)也得這樣
學(xué)java得這樣學(xué),學(xué)習(xí)東西確實(shí)也得這樣2008-02-02
Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之在線蛋糕銷售商城的實(shí)現(xiàn)
這是一個(gè)使用了java+JSP+Springboot+maven+mysql+ThymeLeaf+FTP開發(fā)的在線蛋糕銷售商城,是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有線上蛋糕商城該有的所有功能,感興趣的朋友快來(lái)看看吧2022-01-01
Java ArrayList擴(kuò)容問題實(shí)例詳解
這篇文章主要介紹了Java ArrayList擴(kuò)容問題實(shí)例詳解,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02
詳談Servlet和Filter的區(qū)別以及兩者在Struts2和Springmvc中的應(yīng)用
下面小編就為大家?guī)?lái)一篇詳談Servlet和Filter的區(qū)別以及兩者在Struts2和Springmvc中的應(yīng)用。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2017-08-08
java實(shí)現(xiàn)靜默加載Class示例代碼
這篇文章主要給大家介紹了關(guān)于java實(shí)現(xiàn)靜默加載Class的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10

