1.直接插入排序
(1)基本思想:在要排序的一組數中,假設前面(n-1)[n>=2] 個數已經是排
好順序的,現在要把第n個數插到前面的有序數中,使得這n個數
也是排好順序的。如此反覆循環,直到全部排好順序。
(2)實例
public class insertSort {
public
insertSort(){
inta[]={
49
,
38
,
65
,
97
,
76
,
13
,
27
,
49
,
78
,
34
,
12
,
64
,
5
,
4
,
62
,
99
,
98
,
54
,
56
,
17
,
18
,
23
,
34
,
15
,
35
,
25
,
53
,
51
};
int
temp=
0
;
for
(
int
i=
1
;i<a.length;i++){
int
j=i-
1
;
temp=a[i];
//將大於temp的值整體後移一個單位
for
(;j>=
0
&&temp<a[j];j--){
a[j+
1
]=a[j];
}
a[j+
1
]=temp;
}
for
(
int
i=
0
;i<a.length;i++){
System.out.println(a[i]);
}
}
2. 希爾排序(最小增量排序)
(1)基本思想:算法先將要排序的一組數按某個增量d(n/2,n爲要排序數的個數)分成若干組,每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然後再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。當增量減到1時,進行直接插入排序後,排序完成。
(2)實例:
public class shellSort {
public shellSort(){
int
a[]={
1
,
54
,
6
,
3
,
78
,
34
,
12
,
45
,
56
,
100
};
double
d1=a.length;
int
temp=
0
;
while
(
true
){
d1= Math.ceil(d1/
2
);
int
d=(
int
) d1;
for
(
int
x=
0
;x<d;x++){
for
(
int
i=x+d;i<a.length;i+=d){
int
j=i-d;
temp=a[i];
for
(;j>=
0
&&temp<a[j];j-=d){
a[j+d]=a[j];
}
a[j+d]=temp;
}
}
if
(d==
1
){
break
;
}
for
(
int
i=
0
;i<a.length;i++){
System.out.println(a[i]);
}
}
3.簡單選擇排序
(1)基本思想:在要排序的一組數中,選出最小的一個數與第一個位置的數交換;
然後在剩下的數當中再找最小的與第二個位置的數交換,如此循環到倒數第二個數和最後一個數比較爲止。
(2)實例:
public
class
selectSort {
public
selectSort(){
int
a[]={
1
,
54
,
6
,
3
,
78
,
34
,
12
,
45
};
int
position=
0
;
for
(
int
i=
0
;i<a.length;i++){
int
j=i+
1
;
position=i;
int
temp=a[i];
for
(;j<a.length;j++){
if
(a[j]<temp){
temp=a[j];
position=j;
}
}
a[position]=a[i];
a[i]=temp;
}
for
(
int
i=
0
;i<a.length;i++)
System.out.println(a[i]);
}
}
4.堆排序
(1)基本思想:堆排序是一種樹形選擇排序,是對直接選擇排序的有效改進。
堆的定義如下:具有n個元素的序列(h1,h2,…,hn),當且僅當滿足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,…,n/2)時稱之爲堆。在這裏只討論滿足前者條件的堆。由堆的定義可以看出,堆頂元素(即第一個元素)必爲最大項(大頂堆)。完全二叉樹可以很直觀地表示堆的結構。堆頂爲根,其它爲左子樹、右子樹。初始時把要排序的數的序列看作是一棵順序存儲的二叉樹,調整它們的存儲序,使之成爲一個堆,這時堆的根節點的數最大。然後將根節點與堆的最後一個節點交換。然後對前面(n-1)個數重新調整使之成爲堆。依此類推,直到只有兩個節點的堆,並對它們作交換,最後得到有n個節點的有序序列。從算法描述來看,堆排序需要兩個過程,一是建立堆,二是堆頂與堆的最後一個元素交換位置。所以堆排序有兩個函數組成。一是建堆的滲透函數,二是反覆調用滲透函數實現排序的函數。
(2)實例:
初始序列:46,79,56,38,40,84
建堆:
交換,從堆中踢出最大數
剩餘結點再建堆,再交換踢出最大數
依次類推:最後堆中剩餘的最後兩個結點交換,踢出一個,排序完成。
(3)代碼實現
public class HeapSort {
inta[]={
49
,
38
,
65
,
97
,
76
,
13
,
27
,
49
,
78
,
34
,
12
,
64
,
5
,
4
,
62
,
99
,
98
,
54
,
56
,
17
,
18
,
23
,
34
,
15
,
35
,
25
,
53
,
51
};
public
HeapSort(){
heapSort(a);
}
public
void
heapSort(
int
[] a){
System.out.println(
"開始排序"
);
int
arrayLength=a.length;
//循環建堆
for
(
int
i=
0
;i<arrayLength-
1
;i++){
//建堆
buildMaxHeap(a,arrayLength-
1
-i);
//交換堆頂和最後一個元素
swap(a,
0
,arrayLength-
1
-i);
System.out.println(Arrays.toString(a));
}
}
private
void
swap(
int
[] data,
int
i,
int
j) {
// TODO Auto-generated method stub
int
tmp=data[i];
data[i]=data[j];
data[j]=tmp;
}
//對data數組從0到lastIndex建大頂堆
private void buildMaxHeap(
int
[] data,
int
lastIndex) {
// TODO Auto-generated method stub
//從lastIndex處節點(最後一個節點)的父節點開始
for
(
int
i=(lastIndex-
1
)/
2
;i>=
0
;i--){
//k保存正在判斷的節點
int
k=i;
//如果當前k節點的子節點存在
while
(k*
2
+
1
<=lastIndex){
//k節點的左子節點的索引
int
biggerIndex=
2
*k+
1
;
//如果biggerIndex小於lastIndex,即biggerIndex+1代表的k節點的右子節點存在
if
(biggerIndex<lastIndex){
//若果右子節點的值較大
if
(data[biggerIndex]<data[biggerIndex+
1
]){
//biggerIndex總是記錄較大子節點的索引
biggerIndex++;
}
}
//如果k節點的值小於其較大的子節點的值
if
(data[k]<data[biggerIndex]){
//交換他們
swap(data,k,biggerIndex);
//將biggerIndex賦予k,開始while循環的下一次循環,重新保證k節點的值大於其左右子節點的值
k=biggerIndex;
}
else
{
break
;
}
}
}
}
}
5.冒泡排序
(1)基本思想:在要排序的一組數中,對當前還未排好序的範圍內的全部數,自上而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要求相反時,就將它們互換。
(2)實例:
(3)代碼實現
public
class
bubbleSort {
public bubbleSort(){
inta[]={
49
,
38
,
65
,
97
,
76
,
13
,
27
,
49
,
78
,
34
,
12
,
64
,
5
,
4
,
62
,
99
,
98
,
54
,
56
,
17
,
18
,
23
,
34
,
15
,
35
,
25
,
53
,
51
};
int
temp=
0
;
for
(
int
i=
0
;i<a.length-
1
;i++){
for
(
int
j=
0
;j<a.length-
1
-i;j++){
if
(a[j]>a[j+
1
]){
temp=a[j];
a[j]=a[j+
1
];
a[j+
1
]=temp;
}
}
}
for
(
int
i=
0
;i<a.length;i++){
System.out.println(a[i]);
}
}
6.快速排序
(1)基本思想:選擇一個基準元素,通常選擇第一個元素或者最後一個元素,通過一趟掃描,將待排序列分成兩部分,一部分比基準元素小,一部分大於等於基準元素,此時基準元素在其排好序後的正確位置,然後再用同樣的方法遞歸地排序劃分的兩部分。
(2)實例:
(3)代碼實現
public class quickSort {
inta[]={
49
,
38
,
65
,
97
,
76
,
13
,
27
,
49
,
78
,
34
,
12
,
64
,
5
,
4
,
62
,
99
,
98
,
54
,
56
,
17
,
18
,
23
,
34
,
15
,
35
,
25
,
53
,
51
};
public quickSort(){
quick(a);
for
(
int
i=
0
;i<a.length;i++){
System.out.println(a[i]);
}
}
public int getMiddle(
int
[] list,
int
low,
int
high) {
int
tmp =list[low];
//數組的第一個作爲中軸
while
(low < high){
while
(low < high&& list[high] >= tmp) {
high--;
}
list[low] =list[high];
//比中軸小的記錄移到低端
while
(low < high&& list[low] <= tmp) {
low++;
}
list[high] =list[low];
//比中軸大的記錄移到高端
}
list[low] = tmp;
//中軸記錄到尾
return
low;
//返回中軸的位置
}
public void _quickSort(
int
[] list,
int
low,
int
high) {
if
(low < high){
int
middle =getMiddle(list, low, high);
//將list數組進行一分爲二
_quickSort(list, low, middle -
1
);
//對低字表進行遞歸排序
_quickSort(list,middle +
1
, high);
//對高字表進行遞歸排序
}
}
public void quick(
int
[] a2) {
if
(a2.length >
0
) {
//查看數組是否爲空
_quickSort(a2,
0
, a2.length -
1
);
}
}
}
7、歸併排序
(1)基本排序:歸併(Merge)排序法是將兩個(或兩個以上)有序表合併成一個新的有序表,即把待排序序列分爲若干個子序列,每個子序列是有序的。然後再把有序子序列合併爲整體有序序列。
(2)實例:
(3)代碼實現
public class mergingSort {
inta[]={
49
,
38
,
65
,
97
,
76
,
13
,
27
,
49
,
78
,
34
,
12
,
64
,
5
,
4
,
62
,
99
,
98
,
54
,
56
,
17
,
18
,
23
,
34
,
15
,
35
,
25
,
53
,
51
};
public mergingSort(){
sort(a,
0
,a.length-
1
);
for
(
int
i=
0
;i<a.length;i++)
System.out.println(a[i]);
}
public void sort(
int
[] data,
int
left,
int
right) {
if
(left<right){
//找出中間索引
int
center=(left+right)/
2
;
//對左邊數組進行遞歸
sort(data,left,center);
//對右邊數組進行遞歸
sort(data,center+
1
,right);
//合併
merge(data,left,center,right);  ant; padding:0px!important; background:none!important; border:0px!important; margin:0px!important; bottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; min-height:auto!important">merge(data,left,center,right);
}
}
public void merge(
int
[] data,