生活随笔
收集整理的這篇文章主要介紹了
八大排序-志宇
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
文章目錄
- 冒泡排序
- 選擇排序
- 插入排序
- 希爾排序
- 堆排序
- 大頂堆
- 基數(shù)排序
- 歸并排序
- 快速排序
冒泡排序
思想
比較兩個相鄰元素,如果順序錯誤則交換過來
總共比較數(shù)組長度減一次,每次比較 將 那次比較的最大值放到符合的位置
優(yōu)化: 當(dāng)有一次比較,數(shù)組中沒有數(shù)字交換,則證明數(shù)組已經(jīng)是有序的了
圖解
代碼
import java
.util
.Arrays
;
public class BubbleSort {public static void main(String
[] args
) {int arr
[] ={3, 9, -1, 10, -2};boolean flag
= false;for(int i
=0;i
<arr
.length
-1;i
++){for(int j
=0;j
<arr
.length
-i
-1;j
++){if(arr
[j
] > arr
[j
+1]){flag
= true;int temp
= arr
[j
];arr
[j
] = arr
[j
+1];arr
[j
+1] = temp
;}}System
.out
.println(Arrays
.toString(arr
));if(flag
){flag
= false;}else{break;}}}
}
選擇排序
思想
總共比較數(shù)組長度減一次
在每次比較中記錄最大的數(shù)字的位置
將每次比較出來的最大數(shù)字所在位置和符合的位置進(jìn)行交換
圖解
代碼
import java
.util
.Arrays
;
public class SelectSort {public static void main(String
[] args
) {int[] arr
={101, 34, 119, 1};for(int i
=0;i
<arr
.length
-1;i
++){int min
=i
;for(int j
=i
;j
<arr
.length
;j
++){if(arr
[min
]> arr
[j
]){min
=j
;}}if(min
!=i
){int temp
=arr
[i
];arr
[i
]=arr
[min
];arr
[min
]=temp
;}System
.out
.println(Arrays
.toString(arr
));}}
}
插入排序
思想
好比整理撲克牌的順序,
將要插入的牌拿出來和前一張牌比較,如果前一張牌比這張牌大 前一張牌后移, 要插入的牌再和前第二張牌比較,如果前第二張牌比這張牌大 前第二張牌后移
以此類推,直到找到符合的位置將這張牌插入
缺點
數(shù)組 arr = {2,3,4,5,6,1} 這時需要插入的數(shù) 1(最小), 這樣的過程是:
{2,3,4,5,6,6}
{2,3,4,5,5,6}
{2,3,4,4,5,6}
{2,3,3,4,5,6}
{2,2,3,4,5,6}
{1,2,3,4,5,6}
結(jié)論: 當(dāng)需要插入的數(shù)是較小的數(shù)時,后移的次數(shù)明顯增多,對效率有影響.
圖解
代碼
public class InsertSort {public static void main(String
[] args
) {int[] arr
={101, 34, 119, 1};for(int i
=1;i
<arr
.length
;i
++){int index
=i
;int tempValue
=arr
[i
];while(index
>0 && tempValue
< arr
[index
-1]){arr
[index
]=arr
[index
-1];index
--;}if(index
!=i
){arr
[index
]=tempValue
;}System
.out
.println(Arrays
.toString(arr
));}}
}
希爾排序
思想
希爾排序是 快速排序 基于 分治思想 的改進(jìn)
將數(shù)組分成 數(shù)組長度除二個組(gap) 每個組進(jìn)行插入排序
----只要時大于等于gap的數(shù)字都要要和前面進(jìn)行比較排序
再將數(shù)組分成 gap/2 個數(shù)組進(jìn)行插入排序
當(dāng)gap為1時進(jìn)行最后一次插入排序,即可獲得有序序列
圖解
代碼
public class ShellSort2 {public static void main(String
[] args
) {int[] arr
={8,9,1,7,2,3,5,4,6,0};for(int gap
=arr
.length
/2;gap
>0;gap
=gap
/2){for(int j
=gap
;j
<arr
.length
;j
++){int temp
=arr
[j
];int index
=j
;while(index
-gap
>=0 && temp
<arr
[index
-gap
]){arr
[index
]=arr
[index
-gap
];index
=index
-gap
;}if(index
!= j
){arr
[index
]=temp
;}}System
.out
.println(Arrays
.toString(arr
));}}
}
堆排序
思想
1.將待排序序列構(gòu)造成一個大頂堆
----1.1 找到完全樹的最后一個葉子節(jié)點(有子節(jié)點的節(jié)點)位置為數(shù)組長度/2-1
----1.2 從數(shù)組長度/2-1向前依次進(jìn)行排序
2.此時,整個序列的最大值就是堆頂?shù)母?jié)點。
3.將其與末尾元素進(jìn)行交換,此時末尾就為最大值。
4.然后將剩余n-1個元素重新構(gòu)造成一個堆,這樣會得到n個元素的次小值。
5.如此反復(fù)執(zhí)行,便能得到一個有序序列了。
大頂堆是升序排列,小頂堆是降序排列
圖解
滿二叉樹:
一個二叉樹,如果每一個層的結(jié)點數(shù)都達(dá)到最大值,則這個二叉樹就是滿二叉樹。也就是說,如果一個二叉樹的層數(shù)為K,且結(jié)點總數(shù)是(2^k) -1 ,則它就是滿二叉樹
如下圖: 2^3 -1=7 個節(jié)點
完全二叉樹:
若設(shè)二叉樹的深度為h,除第 h 層外,其它各層 (1~h-1) 的結(jié)點數(shù)都達(dá)到最大個數(shù),第 h 層所有的結(jié)點都連續(xù)集中在最左邊,這就是完全二叉樹
大頂堆
大頂堆:是完全二叉樹,每個節(jié)點的值大于或等于它的左子節(jié)點和右子節(jié)點的值,沒有要求結(jié)點的左子節(jié)點的值和右子節(jié)點的值的大小關(guān)系。
我們對堆中的結(jié)點按層進(jìn)行編號,映射到數(shù)組中就是下面這個樣子:
大頂堆特點:
arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] // i 對應(yīng)第幾個節(jié)點,i從0開始編號
小頂堆
小頂堆:是完全二叉樹,每個節(jié)點的值小于或等于它的左子節(jié)點和右子節(jié)點的值,沒有要求結(jié)點的左子節(jié)點的值和右子節(jié)點的值的大小關(guān)系。
代碼
public class HeapSort2 {public static void main(String
[] args
) {int[] arr
={4,6,8,5,9};for(int i
=arr
.length
/2-1;i
>=0;i
--){maxHeapSort(arr
,i
,arr
.length
);}System
.out
.println(Arrays
.toString(arr
));for(int i
=0;i
<arr
.length
;i
++){maxHeapSort(arr
,0,arr
.length
-i
);int temp
=arr
[0];arr
[0]=arr
[arr
.length
-i
-1];arr
[arr
.length
-i
-1]=temp
;System
.out
.println(Arrays
.toString(arr
));}}private static void maxHeapSort(int[] arr
, int i
, int length
) {int temp
=arr
[i
];for(int k
=2*i
+1;k
<length
;k
=2*k
+1){if(k
+1<length
&& arr
[k
+1]>arr
[k
]){k
++;}if(temp
< arr
[k
]){arr
[i
]=arr
[k
];i
=k
;}else{break;}arr
[k
]=temp
;}}
}
基數(shù)排序
思想
----計數(shù)排序:每個桶只存儲單一鍵值;
----桶排序:每個桶存儲一定范圍的數(shù)值;
----基數(shù)排序:根據(jù)鍵值的每位數(shù)字來分配桶;
1、創(chuàng)建桶
----1.1如果排序是數(shù)字則創(chuàng)建10個桶,每個桶最大容量為序列長度
----1.2如果排序的是字母創(chuàng)建26個桶,每個桶最大容量為序列長度
----1.3創(chuàng)建一個數(shù)組用來標(biāo)記每個桶中有多少個元素
2、將序列按要求放到桶中
----2.2 遍歷序列中每個元素,獲得指定位上的值
----2.3 根據(jù)獲得指定位上的值將元素放到指定桶中,標(biāo)記桶中元素個數(shù)的值增加
3、從桶中取出
----3.3按順序遍歷桶中的值,同時將值賦值給原數(shù)組
4、循環(huán)2和3最后得出有序序列
注意: 基數(shù)排序是經(jīng)典的空間換時間的方式,占用內(nèi)存很大, 當(dāng)對海量數(shù)據(jù)排序時,容易造成 OutOfMemoryError
圖解
代碼
public class RadixSort2 {public static void main(String
[] args
) {int[]arr
= {73, 22, 93, 43, 55, 14, 28, 65, 39, 81, 33, 100};sort(arr
,3);System
.out
.println(Arrays
.toString(arr
));}private static void sort(int[] arr
, int length
) {int[][] tempArr
=new int[10][arr
.length
];int[] indexArr
=new int[10];for(int i
=0,n
=1;i
<length
;i
++,n
=n
*10){for(int j
=0;j
<arr
.length
;j
++){int val
=arr
[j
]/n
%10;tempArr
[val
][indexArr
[val
]++]=arr
[j
];}int index
=0;for(int k
=0;k
<10;k
++){for(int l
=0;l
<indexArr
[k
];l
++){arr
[index
]=tempArr
[k
][l
];index
++;}}indexArr
=new int[10];}}
}
歸并排序
思想
采用分治思想,將數(shù)組拆分成每一個元素,然后合并時進(jìn)行排序
圖解
拆分
合并
綠色數(shù)組 和 紅色數(shù)組 合并為一個 藍(lán)色數(shù)組(temp數(shù)組)
藍(lán)色和紅色數(shù)組各有一個指針,通過比較指針后移按大小順序取出放入temp數(shù)組中
代碼
public class MergeSort {public static void main(String
[] args
) {int[] arr
={9,8,7,6,5,4,3,2,1}; int[] temp
=new int[arr
.length
];merge(arr
,0,arr
.length
-1,temp
);System
.out
.println(Arrays
.toString(arr
));}private static void merge(int[] arr
, int l
, int r
, int[] temp
) {if(l
<r
){int mid
=(l
+r
)/2;merge(arr
,l
,mid
,temp
);merge(arr
,mid
+1,r
,temp
);mergeSort(arr
,l
,mid
,r
,temp
);System
.out
.println(Arrays
.toString(arr
));}}private static void mergeSort(int[] arr
, int l
, int mid
, int r
, int[] temp
) {int left
=l
; int right
=mid
+1; int index
=l
; while(left
<=mid
&& right
<=r
){if(arr
[left
]<=arr
[right
]){temp
[index
]=arr
[left
];index
++;left
++;}else{temp
[index
]=arr
[right
];index
++;right
++;}}while(left
<=mid
){temp
[index
]=arr
[left
];index
++;left
++;}while(right
<=r
){temp
[index
]=arr
[right
];index
++;right
++;}for(int i
=l
;i
<=r
;i
++){arr
[i
]=temp
[i
];}}
}
快速排序
思想
采用分治思想
1.首先選取一個基準(zhǔn)數(shù)
2.將小于基準(zhǔn)數(shù)的數(shù)放倒基準(zhǔn)數(shù)的左面
3.將大于基準(zhǔn)數(shù)的數(shù)放到基準(zhǔn)數(shù)的右面
4.一次遞歸拆分,直到數(shù)組有序
圖解
1.首先選取一個基準(zhǔn)數(shù),這里選擇基準(zhǔn)數(shù)為19
設(shè)置最左面的位置為L
設(shè)置最右面的位置為R
2.將R處索引中的8和基準(zhǔn)數(shù)進(jìn)行比較,由于比基準(zhǔn)數(shù)小則將8放到L索引處位置,
同時L索引后移一位
3.將L處索引數(shù)值取出和基準(zhǔn)數(shù)比較,由于比基準(zhǔn)數(shù)大,將97放到R處索引位置,同時R索引前移一位
4.將R處索引上的值和基準(zhǔn)數(shù)比較,由于1比基準(zhǔn)數(shù)小,將1放到L索引位置,同時L的索引后移1位
5.將L索引處的數(shù)和基準(zhǔn)數(shù)比較,由于9比基準(zhǔn)數(shù)小,L直接后移一位
將L索引處的數(shù)和基準(zhǔn)數(shù)比較,由于17比基準(zhǔn)數(shù)小,L直接后移一位
6.在L和R重合了,這時將基準(zhǔn)數(shù)插入到重合的位置,得到第一次排序
代碼
public class QuickSort {public static void main(String
[] args
) {int[] arr
={-9,78,0,23,-567,70};quickSort(arr
,0,arr
.length
-1);System
.out
.println(Arrays
.toString(arr
));}private static void quickSort(int[] arr
, int left
, int right
) {if(left
<right
){int pivot
=arr
[left
];int l
=left
;int r
=right
;while (l
< r
){while(l
<r
&& arr
[r
]>pivot
){r
--;}if(l
<r
){arr
[l
]=arr
[r
];l
++;}while(l
<r
&& arr
[l
]<pivot
){l
++;}if(l
<r
){arr
[r
]=arr
[l
];r
--;}}arr
[l
]=pivot
;System
.out
.println(Arrays
.toString(arr
));quickSort(arr
,left
,l
-1);quickSort(arr
,l
+1,right
);}}
}
總結(jié)
以上是生活随笔為你收集整理的八大排序-志宇的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。