文章目錄
算法分類
- 比較類算法:通過比較決定元素的次序,時間複雜度不能突破O(nlogn)。非線性時間比較器
- 非比較類算法:不同比較,可以突破基於比較排序的事件下界。線性時間比較器
1、 冒泡排序(交換排序)
1.1、基本思想
在無序區交換最大元素到最右邊,交換n-1躺。
結果:將最大值放到最終位置
1.1、算法具體描述
a) 比較相鄰的兩個數,如果第二個數大,就交換位置
b) 從左到右進行比較,直到將最大值交換到最右邊
c) 依此類推,交換n-1躺
1.2、Java代碼實現
public static int[] BubbleSort(int[] arry){
for (int i=0;i<arry.length-1;i++){ //總共交換(arry.length-1)輪,依此將第1,2,3,,,n-1大的數找出來
Boolean flag=false; //沒有進行交換
for(int j=0;j<arry.length-1-i;j++){ //每輪交換的起始位置
if(arry[j]>arry[j+1]){ //比較相鄰的兩元素
swap(arry,j,j+1);
flag=true;
}
}
if(!flag){break;}
}
return arry;
}
2、
3、選擇排序(選擇排序)
3.1、基本思路
在無序區選擇最小值放到最左邊,選擇n-1躺
3.1、算法具體描述
a) 首先從未排序隊列中找到最小元素,存放到第一個位置
b) 然後從未排序隊列中找到第二小元素,存放到第二個位置
c) 依此類推,重複n-1躺
3.3、Java實現
/**
* 進行簡單選擇排序
*/
public static int[] SelectSort(int[] arry){
for (int i=0;i<arry.length-1;i++){ //選擇的躺數n-1躺
int min=i; //暫存最小值小標,而不能暫存最小值
for (int j=i+1;j<arry.length;j++){
if(arry[j]<arry[min]){
// arry[min]=arry[j];
min=j;
}
}
swap(arry,min,i);
}
return arry;
}
4、插入排序(區別冒泡和選擇,操作有序區進行排序)
4.1、基本思想
向有序區插入相應位置,插入n-1躺。
4.2、算法具體描述
a) 假設第一個元素已經排好序
b) 插入已排好序的有序區,插入n-1躺
c) 若找到比該值大的向後移,直到找到比該值小的。
4.3、Java實現
/**
* 進行插入排序
*/
public static int[] InsertSort(int[] arry){
int pre,curr;
for (int i=1;i<arry.length;i++){ //i表示下標
pre=i-1;
curr=arry[i]; //當前處理的數字
while(pre>=0 && arry[pre]>curr){ //查找比當前數字小的並且右移,然後插入相應的位置
arry[pre+1]=arry[pre];
pre--;
}
arry[pre+1]=curr;
}
return arry;
}
2、快速排序(交換排序)
2.1、基本思路
(分治法)通過一趟排序將數列分割成分組有序的兩部分,然後遞歸的排序子數列
結果:將樞軸放到最終位置
2.2、算法具體實現
a) 選一個 基準,將比基準大的向右移動,將比樞軸小的向左移動
b) 遞歸的排序子數列
2.3、Java實現
/**
* 進行快速排序:添加兩個指針
* 1. 將樞軸放到最終位置,並保持分區有序
* 2. 遞歸進行排序
*/
public static int[] QuickSort(int[] arry,int low,int hight){
if(low<hight){ //遞歸跳出條件
int pivot=partition(arry,low,hight);//進行分區,返回樞軸的索引(而不是樞軸的值)
QuickSort(arry,0,pivot-1);
QuickSort(arry,pivot+1,hight);
}
return arry;
}
/**
* 通過樞軸對數組進行劃分,劃分方式
* 5(low),2,1,7,3,4,8,0(hight)
* 0(low),2,1,7,3,4,8,5(hight)
* 0,2,1,5(low),3,4,8,7(hight)
* 0,2,1,4(low),3,5(hight),8,7
* 0,2,1,4,3,5(low,hight),8,7
* 通過樞軸對數組進行劃分,劃分方式是從右邊找到一個比樞軸小的移動到low位置,從左邊找到一個比樞軸大的移動到hight位置
* 5(low),2,1,7,3,4,8,0(hight)
* 0(low),2,1,7,3,4,8,0(hight)
* 0,2,1,7(low),3,4(hight),8,7
* 0,2,1,4,3,4(low,hight),8,7
* 0,2,1,4,3,5(low,hight),8,7
* @return
*/
public static int partition(int[] a,int low,int hight){
int pivot=a[low];//將數組第一個作爲樞軸值,將其暫存到某變量
while(low<hight){ //循環跳出條件
while(low<hight && a[hight]>=pivot) --hight; //找到比樞軸小的元素移動=hight(比樞軸大的向左移動,直到找到)
a[low]=a[hight]; //將比樞軸小的移動到右邊
while(low<hight && a[low]<=pivot) ++low; //找到比樞軸大的元素=low
a[hight]=a[low]; //將比樞軸大的移動到右邊
}
a[low]=pivot; //將樞軸元素存放到最終位置,將交換優化到了移動
return low;
}