目錄:
- 冒泡排序(Bubble Sort)
- 插入排序(Insertion Sort)
- 選擇排序(Selection Sort)
- 希爾排序(Shell Sort)
- 歸併排序(Merge Sort)
算法複雜度:
排序方法 | 時間複雜度(最好) | 時間複雜度(最壞) | 時間複雜度 (平均) | 空間複雜度 | 穩定性 |
---|---|---|---|---|---|
冒泡排序 | O(n) | O(n2) | O(n2) | O(1) | 穩定 |
插入排序 | O(n) | O(n2) | O(n2) | O(1) | 穩定 |
選擇排序 | O(n2) | O(n2) | O(n2) | O(1) | 不穩定 |
希爾排序 | O(n) | O(n2) | O(nlgn) | O(1) | 不穩定 |
歸併排序 | O(nlgn) | O(nlgn) | O(nlgn) | O(n) | 穩定 |
- 冒泡排序:
冒泡排序是比較排序,若第一個比第二個大,則交換位置。類似重的元素下沉,而輕的元素上浮。
import java.util.Scanner;
public class BubbleSort {
public static void main(String[] args){
final int maxLength; //輸入數組的長度
int i,j;
int temp; //臨時變量
Scanner setLength=new Scanner(System.in); //通過Scanner類獲得用戶輸入的整形變量
System.out.print("請輸入需要排序的數組的長度:");
maxLength=setLength.nextInt();
int[] array=new int[maxLength];
Scanner input=new Scanner(System.in); //獲得一組數組的值
System.out.print("請輸入數組:");
for(i=0;i<array.length;i++){
array[i]=input.nextInt();
}
//冒泡排序
for(i=1;i<array.length;i++){ //n-1次外層循環
for(j=i;j>0;j--){
if(array[j]<array[j-1]){ //比較與前一個數的大小關係
temp=array[j]; //若小於前一個數,則向上冒泡
array[j]=array[j-1];
array[j-1]=temp;
}
}
}
System.out.print("經冒泡排序後的數組爲:"); //輸出最終排序結果
for(i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
}
}
-
插入排序:
插入排序是一種簡單且穩定的排序算法。算法的基本思想是將一組待排的數組分成兩組(默認先有第一個數組值),再依此遍歷之後的所有的數。比較其與之前已經排好的數組,若此值(target)小於前一個數,則前一個數向後移動一位。(注意是向後移動,而非交換位置)
import java.util.Scanner;
public class InsertionSort {
public static void main(String[] args){
final int maxLength; //輸入數組的長度
int i,j;
int target;
Scanner setLength=new Scanner(System.in); //通過Scanner類獲得用戶輸入的整形變量
System.out.print("請輸入需要排序的數組的長度:");
maxLength=setLength.nextInt();
int[] array=new int[maxLength];
Scanner input=new Scanner(System.in); //獲得一組數組的值
System.out.print("請輸入數組:");
for(i=0;i<array.length;i++){
array[i]=input.nextInt();
}
//插入排序算法
for(i=1;i<array.length;i++){ //n-1次遍歷
j=i;
target=array[j]; //target爲新來的一個元素
while (j>0&&target<array[j-1]){
array[j]=array[j-1]; //大於target的元素後移一個位置
j--;
}
array[j]=target;
}
System.out.print("經插入排序後的數組爲:"); //輸出最終排序結果
for(i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
}
}
-
選擇排序:
選擇排序算法的基本思想是每次從待排序的數據元素中選擇出最小的元素,標記其位置。通過與第一個元素交換位置達到排序目的。然後從剩餘的未排序的元素中尋找最小元素,將其放在已派序列的開始位置。選擇排序是通過比較數的大小來交換,已達到排序目的。
import java.util.Scanner;
public class SelectionSort {
public static void main(String[] args){
final int maxLength; //輸入數組的長度
int i,j;
int temp; //臨時變量
Scanner setLength=new Scanner(System.in); //通過Scanner類獲得用戶輸入的整形變量
System.out.print("請輸入需要排序的數組的長度:");
maxLength=setLength.nextInt();
int[] array=new int[maxLength];
Scanner input=new Scanner(System.in); //獲得一組數組的值
System.out.print("請輸入數組:");
for(i=0;i<array.length;i++){
array[i]=input.nextInt();
}
//選擇排序算法
for(i=0;i<array.length-1;i++){ //n-1次循環
int k=i;
for (j=k+1;j<array.length;j++){
if(array[j]<array[k]){
k=j; //以k記錄本輪最小值所在位置
}
}
if(i!=k){ //找到當前本輪最小值後,交換位置
temp=array[i];
array[i]=array[k];
array[k]=temp;
}
}
System.out.print("經選擇排序後的數組爲:"); //輸出最終排序結果
for(i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
}
}
-
希爾排序
希爾排序可以說是簡單插入排序的增強版。希爾排序不像插入排序那樣循規蹈矩,一步一步進行。而是採取跳躍式分組的策略,通過某個增量將元素(gap)劃分爲若干組,然後分組插入排序。隨後逐步減小增量,繼續按組進行插入排序,直至增量爲1。(gap的選擇是影響希爾排序性能的重要因素)
import java.util.Scanner;
public class ShellSort {
public static void main(String[] args){
final int maxLength; //輸入數組的長度
int i,j;
int temp; //臨時變量
int gap; //增量
Scanner setLength=new Scanner(System.in); //通過Scanner類獲得用戶輸入的整形變量
System.out.print("請輸入需要排序的數組的長度:");
maxLength=setLength.nextInt();
int[] array=new int[maxLength];
Scanner input=new Scanner(System.in); //獲得一組數組的值
System.out.print("請輸入數組:");
for(i=0;i<array.length;i++){
array[i]=input.nextInt();
}
//希爾排序
for(gap=array.length/2;gap>0;gap/=2){ //逐步減小增量
for(i=gap;i<array.length;i++){ //從第gap個元素開始,逐個進行插入排序
j=i;
while(j-gap>=0&&array[j]<array[j-gap]){ //比較已達到交換的目的
temp=array[j];
array[j]=array[j-gap];
array[j-gap]=temp;
j-=gap;
}
}
}
System.out.print("經希爾排序後的數組爲:"); //輸出最終排序結果
for(i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
}
}
- 歸併排序
歸併排序主要算法思想是分治,分而治之,然後將之歸併,如下動圖。歸併排序是一種較穩定的排序方法,採取這種類似二叉樹的方法,算法的時間複雜度爲O(nlogn)。
import java.util.Scanner;
public class MergeSort {
public static void main(String[] args){
final int maxLength; //輸入數組的長度
int i,j;
int temp; //臨時變量
Scanner setLength=new Scanner(System.in); //通過Scanner類獲得用戶輸入的整形變量
System.out.print("請輸入需要排序的數組的長度:");
maxLength=setLength.nextInt();
int[] array=new int[maxLength];
Scanner input=new Scanner(System.in); //獲得一組數組的值
System.out.print("請輸入數組:");
for(i=0;i<array.length;i++){
array[i]=input.nextInt();
}
//歸併排序
sort(array);
System.out.print("經歸併排序後的數組爲:"); //輸出最終排序結果
for(i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
}
//
//歸併排序
public static void sort(int []arr){
int []temp = new int[arr.length]; //在排序前,先建好一個長度等於原數組長度的臨時數組,避免遞歸中頻繁開闢空間
sort(arr,0,arr.length-1,temp);
}
private static void sort(int[] arr,int left,int right,int []temp){
if(left<right){
int mid = (left+right)/2;
//遞歸的方法
sort(arr,left,mid,temp); //左邊歸併排序,使得左子序列有序
sort(arr,mid+1,right,temp);//右邊歸併排序,使得右子序列有序
merge(arr,left,mid,right,temp);//將兩個有序子數組合並操作
}
}
private static void merge(int[] arr,int left,int mid,int right,int[] temp){
int i = left; //左序列指針
int j = mid+1; //右序列指針
int t = 0; //臨時數組指針
while (i<=mid && j<=right){
if(arr[i]<=arr[j])
temp[t++] = arr[i++];
else
temp[t++] = arr[j++];
}
while(i<=mid){ //將左邊剩餘元素填充進temp中
temp[t++] = arr[i++];
}
while(j<=right){ //將右序列剩餘元素填充進temp中
temp[t++] = arr[j++];
}
t = 0;
//將temp中的元素全部拷貝到原數組中
while(left <= right){
arr[left++] = temp[t++];
}
}
}