Java實現:排序演算法--時間複雜度為O(n² )
為什麼要學習時間複雜度為O(n² )?
3.在一些特殊情況下,簡單的排序演算法更有效
4.簡單的排序演算法思想衍生出複雜的排序演算法
1.選擇排序
選擇排序,就是每一次都篩選出最小(或最大)的數字,然後放在每一次排序的第幾個位置。
比如第一次排序,找出最小(或最大)的元素,放在第一個位置,第二次排序,找出最小(或最大)的元素,放在第二個位置.....
順序從小到大排序:
首先選出最小元素:“1”
然後將這個“1”和第一個位置進行交換:
此時的“1”是在最終位置了,可以不去理會了。
接著找出剩餘還沒排序的最小元素:“2”
跟第二個位置進行交換:
以此類推進行排序,這種排序就是選擇排序了。
public class SelectionSort {
public static void swap(Object[]arr , int i , int j){
Object obj = arr[i];
arr[i] = arr[j];
arr[j] = obj;
}
public static void sort_asc(Comparable[] arr){
int n = arr.length -1;
for( int i = 0 ; i <= n ; i++ ){
for( int j = i+1 ; j <= n ; j++ ){
if( arr[j].compareTo(arr[i]) < 0 ){
swap(arr,i,j);
}
}
}
}
public static void main(String[] args) {
Integer [] arr = {10,3,5,2,4,1,8,6,7,9};
sort_asc(arr);
for( int i : arr ){
System.out.print(i + " ");
}
}
}
2.插入排序
插入排序,從前(或往後),第n次排序,則對n個元素進行排序。
例如第一次排序,對於“8”來說,已經排序完畢了。
第二次排序,對於“6”來說,要放到前面合適的位置。
比“8”還要小,放在前面的位置。
第三次排序,對於“2”來說,要放在前面3個元素合適的位置。
“2”比“8”小。
“2”比“6”小,繼續交換一次位置。
進行多次的資料交換。
這樣前面3個元素就排序完成了。以此類推排序完成......
public class InsertionSort {
public static void swap(Object[]arr , int i , int j){
Object obj = arr[i];
arr[i] = arr[j];
arr[j] = obj;
}
public static void sort_asc(Comparable[]arr){
int n = arr.length - 1;
for( int i = 1 ; i <= n ; i++ ) {
//尋找元素arr[i]適合插入的位置
for( int j = i ; j > 0 ; j--) {
if( arr[j].compareTo(arr[j-1]) < 0 ) {
swap(arr,j,j-1);
} else {
//如果不小於,則已排序完成,可以跳出當前迴圈,進行下一個迴圈
break;
}
}
}
}
public static void main(String[] args) {
Integer [] arr = {10,3,5,2,4,1,8,6,7,9};
sort_asc(arr);
for( int i : arr ){
System.out.print(i + " ");
}
}
}
對於比較插入排序和選擇排序。
在插入排序中:
public static void InsertSort(Comparable[]arr){
int n = arr.length - 1;
for( int i = 1 ; i <= n ; i++ ) {
//尋找元素arr[i]適合插入的位置
for( int j = i ; j > 0 ; j--) {
if( arr[j].compareTo(arr[j-1]) < 0 ) {
swap(arr,j,j-1);
} else {
//如果不小於,則已排序完成,可以跳出當前迴圈,進行下一個迴圈
break;
}
}
}
}
有一個break操作,能夠節省一些時間。
所以理應來說比較於“選擇排序”來說,要快的很多。
但是其實不然,選擇排序只是每一次進行一次資料的交換操作(swap)。
而插入排序在每一次的排序中要進行多次的資料交換操作(swap裡面有3次賦值的操作),所以對於一個break語句來說,其實並沒有快的多少。
所以能不能改變一下演算法,讓插入排序也能只進行一次資料交換呢?答案是完全可以的
改進的插入排序:
第一次排序“8”還是在那裡:
在第二次排序,“6”的位置的時候,不像之前那樣冒然交換了。
而是先把“6”複製一份,儲存起來。
然後看“6”是否合適放在當前位置。
那麼判斷是否合適放在當前位置,比較這兩位數的大小,“6”比“8”小,所以不能放在當前位置。
所以把“8”向後移動一個位置,直接在當前位置進行賦值,而不是交換:
然後再來考察“6”,是否能放在前一個位置:
此時的位置是第一個,所以不用比較了:
接下來看”2“,直接複製一個副本:
因為 “2” 比前面 “8”小,所以“2”不能放在這個位置,此時“8”賦值到“2”這個位置:
然後再次判斷 “2”是不是應該放在之前“8”這個位置,跟前面的“6”比較,不是:
所以把“6”賦值到這個位置:
然後再來看 “2”是不是應該放在原來 “6”放的位置:
因為是第0個位置:所以直接賦值就好了:
依次類推,不用一次排序進行多次資料的交換,而是變成資料的賦值操作。
程式碼如下:
public static void changeSort(Integer [] arr){
for( int i = 1 ; i < arr.length ; i++ ){
//尋找元素arr[i]適合的插入位置
int temp = arr[i];
//j儲存元素temp應該插入的位置
int j;
for( j = i ; j > 0 && arr[j-1] > temp ; j-- ){
arr[j] = arr[j-1];
}
arr[j] = temp;
}
}
4.氣泡排序
顧名思義:像冒泡泡一樣上升。
對於一個陣列,有n個元素。
第一輪排序下來,把最大(或最小)的資料給篩選出來,放在陣列的最右(或最左),
然後進行第二輪排序,找出第二大(或次小)的資料,放在陣列的[n-2](或[1]),
....
依次類推,進行第n輪排序,資料便以排序完成。
所以氣泡排序需要兩個迴圈:
public class BubbleSort {
public static void swap(Object[]arr , int i , int j){
Object obj = arr[i];
arr[i] = arr[j];
arr[j] = obj;
}
public static void sort_asc(Comparable[]arr){
for(int i = arr.length-1 ; i >= 0 ; i-- ){
for( int j = i-1 ; j >= 0 ; j-- ){
if(arr[i].compareTo(arr[j]) < 0){
swap(arr,i,j);
}
}
}
}
public static void main(String[] args) {
Integer [] arr = {10,3,5,2,4,1,8,6,7,9};
sort_asc(arr);
for( int i : arr ){
System.out.print(i + " ");
}
}
}
相關文章
- 時間複雜度為 O (n^2) 的排序演算法時間複雜度排序演算法
- 時間複雜度為 O(n^2) 的排序演算法時間複雜度排序演算法
- 時間複雜度O(n)和空間複雜度時間複雜度
- 時間複雜度為 O(nlogn) 的排序演算法時間複雜度排序演算法
- 時間複雜度為O(nlogn)的排序演算法時間複雜度排序演算法
- 時間複雜度O(1)、O(n)、O(n²)、O(nlogn)的含義時間複雜度
- 排序演算法:堆排序的實現和時間複雜度分析排序演算法時間複雜度
- Leetcode 234. 迴文連結串列 快慢指標+連結串列逆序實現O(n)時間複雜度且O(1)空間複雜度LeetCode指標時間複雜度
- 快速排序平均時間複雜度O(nlogn)的推導排序時間複雜度
- 判斷連結串列是否為迴文結構,空間負責度為O(1),時間複雜度為O(n)時間複雜度
- 【漫畫】為什麼說O(n)複雜度的基數排序沒有快速排序快?複雜度排序
- 氣泡排序時間複雜度分析排序時間複雜度
- 隨機列印0-100的全部數字並且不可重複,時間複雜度為O(n)隨機時間複雜度
- 如何不用演算法對陣列進行(0時間複雜度,0空間複雜度)排序?演算法陣列時間複雜度排序
- 時間複雜度跟空間複雜度時間複雜度
- 時間複雜度與空間複雜度時間複雜度
- 時間複雜度和空間複雜度時間複雜度
- 演算法的時間複雜度演算法時間複雜度
- 演算法(一)時間複雜度演算法時間複雜度
- 演算法分析__時間複雜度演算法時間複雜度
- 卷演算法——時間複雜度演算法時間複雜度
- 解惑3:時間頻度,演算法時間複雜度演算法時間複雜度
- 122 演算法的時間複雜度和空間複雜度詳解演算法時間複雜度
- 演算法題:O(1)時間複雜度實現獲取棧的最大值、最小值演算法時間複雜度
- PHP 演算法基礎----時間複雜度和空間複雜度(轉載)PHP演算法時間複雜度
- 時間複雜度怎麼算?如何計算時間複雜度?時間複雜度
- 遞迴演算法的時間複雜度遞迴演算法時間複雜度
- 【基礎】演算法的時間複雜度分析演算法時間複雜度
- 時間複雜度 – Java那些事兒專欄時間複雜度Java
- 圖解時間複雜度圖解時間複雜度
- 淺談時間複雜度時間複雜度
- dfs時間複雜度分析時間複雜度
- 時間複雜度(詳解)時間複雜度
- 說說你對演算法中時間複雜度,空間複雜度的理解?如何計算?演算法時間複雜度
- 用機器學習構建O(N)複雜度的排序演算法,可在GPU和TPU上加速計算機器學習複雜度排序演算法GPU
- 用一個測試類簡化排序演算法時間複雜度的研究排序演算法時間複雜度
- 常見排序演算法及複雜度排序演算法複雜度
- 時間與空間複雜度分析複雜度