前言
在學習過程中,演算法是我們繞不過去的檻,可能我們沒有特體經過系統的學習,但是,實際上平時的**中已經體現了很多的演算法思想,以中興演算法大賽2023年中興演算法大賽 迪傑特斯拉派為列,裡面自己其實用到了很多演算法,只是自己並沒有將它與理論結合起來看。
1.概述
首先,我們來看一張經典的圖,這張圖很詳細講常見的演算法做了歸類:
排序有內部排序和外部排序,內部排序是資料記錄在記憶體中進行排序,而外部排序是因排序的資料很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。
我們這裡說說八大排序就是內部排序。
先看一下他們的複雜度,然後再分別對他們介紹,比較,總吉他們的優點,分析適用的場景。
-1.選擇排序:不穩定,時間複雜度 o(n^2)
選擇排序的基本思想是對待排序的記錄序列進行n-1遍的處理,第i遍處理是將l[i..n]中最小者與l[i]交換位置。這樣,經過i遍處理之後,前i個記錄的位置已經是正確的了。
- 2.插入排序:穩定,時間複雜度 o(n^2)
插入排序的基本思想是,經過i-1遍處理後,l[1..i-1]己排好序。第i遍處理僅將l[i]插入l[1..i-1]的適當位置,使得l[1..i] 又是排好序的序列。要達到這個目的,我們可以用順序比較的方法。首先比較l[i]和l[i-1],如果l[i-1]≤ l[i],則l[1..i]已排好序,第i遍處理就結束了;否則交換l[i]與l[i-1]的位置,繼續比較l[i-1]和l[i-2],直到找到某乙個位置j(1≤j≤i-1),使得l[j] ≤l[j+1]時為止。圖1演示了對4個元素進行插入排序的過程,共需要(a),(b),(c)三次插入。
- 3.氣泡排序:穩定,時間複雜度 o(n^2)
氣泡排序方法是最簡單的排序方法。這種方法的基本思想是,將待排序的元素看作是豎著排列的「氣泡」,較小的元素比較輕,從而要往上浮。在氣泡排序演算法中我們要對這個「氣泡」序列處理若干遍。所謂一遍處理,就是自底向上檢查一遍這個序列,並時刻注意兩個相鄰的元素的順序是否正確。如果發現兩個相鄰元素的順序不對,即「輕」的元素在下面,就交換它們的位置。顯然,處理一遍之後,「最輕」的元素就浮到了最高位置;處理二遍之後,「次輕」的元素就浮到了次高位置。在作第二遍處理時,由於最高位置上的元素已是「最輕」元素,所以不必檢查。一般地,第i遍處理時,不必檢查第i高位置以上的元素,因為經過前面i-1遍的處理,它們已正確地排好序。
- 4.堆排序:不穩定,時間複雜度 o(nlog n)
堆排序是一種樹形選擇排序,在排序過程中,將a[n]看成是完全二叉樹的順序儲存結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關係來選擇最小的元素。
- 5.歸併排序:穩定,時間複雜度 o(nlog n)
設有兩個有序(公升序)序列儲存在同一陣列中相鄰的位置上,不妨設為a[l..m],a[m+1..h],將它們歸併為乙個有序數列,並儲存在a[l..h]。
- 6.快速排序:不穩定,時間複雜度 最理想 o(nlogn) 最差時間o(n^2)
快速排序是對氣泡排序的一種本質改進。它的基本思想是通過一趟掃瞄後,使得排序序列的長度能大幅度地減少。在氣泡排序中,一次掃瞄只能確保最大數值的數移到正確位置,而待排序序列的長度可能只減少1。快速排序通過一趟掃瞄,就能確保某個數(以它為基準點吧)的左邊各數都比它小,右邊各數都比它大。然後又用同樣的方法處理它左右兩邊的數,直到基準點的左右只有乙個元素為止。
-7.希爾排序:不穩定,時間複雜度 平均時間 o(nlogn) 最差時間o(n^s)
在直接插入排序演算法中,每次插入乙個數,使有序序列只增加1個節點,並且對插入下乙個數沒有提供任何幫助。如果比較相隔較遠距離(稱為 增量)的數,使得數移動時能跨過多個元素,則進行一次比較就可能消除多個元素交換。d.l.shell於2023年在以他名字命名的排序演算法中實現了這一思想。演算法先將要排序的一組數按某個增量d分成若干組,每組中記錄的下標相差d.對每組中全部元素進行排序,然後再用乙個較小的增量對它進行,在每組中再進行排序。當增量減到1時,整個要排序的數被分成一組,排序完成。
2.演算法介紹
2.1 插入排序—直接插入排序(straight insertion sort)
基本思想:
將乙個記錄插入到已排序好的有序表中,從而得到乙個新,記錄數增1的有序表。即:先將序列的第1個記錄看成是乙個有序的子串行,然後從第2個記錄逐個進行插入,直至整個序列有序為止。
要點:設立哨兵,作為臨時儲存和判斷陣列邊界之用。
如果碰見乙個和插入元素相等的,那麼插入元素把想插入的元素放在相等元素的後面。所以,相等元素的前後順序沒有改變,從原無序序列出去的順序就是排好序後的順序,所以插入排序是穩定的。
演算法的實現:
public
static
void selectsort(int array)
} array[position] = array[i];
array[i] = temp;
} system.out.println(arrays.tostring(array) + " selectsort");
}
2.2 希爾排序
基本思想:
希爾排序,也稱遞減增量排序演算法,是插入排序的一種更高效的改進版本。希爾排序是非穩定排序演算法。
希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
插入排序在對幾乎已經排好序的資料操作時,效率高,即可以達到線性排序的效率;
但插入排序一般來說是低效的,因為插入排序每次只能將資料移動一位。
先取乙個正整數d1 < n, 把所有相隔d1的記錄放一組,每個組內進行直接插入排序;然後d2 < d1,重複上述分組和排序操作;直至di = 1,即所有記錄放進乙個組中排序為止。
演算法實現:
public
static
void shellsort(int array)
for (; gap > 0; gap /= 3)
array[j + gap] = temp;
} }
system.out.println(arrays.tostring(array) + " shellsort");
}
2.3 簡單排序
基本思想:
基本思想:在要排序的一組數中,選出最小的乙個數與第乙個位置的數交換;
演算法實現:
public
static
void
selectsort(int number)
/* * 第二步:對堆化資料排序
* 每次都是移出最頂層的根節點a[0],與最尾部節點位置調換,同時遍歷長度 - 1。
* 然後從新整理被換到根節點的末尾元素,使其符合堆的特性。
* 直至未排序的堆長度為 0。
*/for (int i = len; i > 0; i--)
system.out.println(arrays.tostring(array) + " heapsort");
} private
static
void
swap(int i, int j, int arr)
/**
* 調整索引為 index 處的資料,使其符合堆的特性。
* *@param index 需要堆化處理的資料的索引
*@param len 未排序的堆(陣列)的長度
*/private
static
void
maxheapify(int index, int len, int arr)
if (ri <= len && arr[ri] > arr[li]) // 先判斷左右子節點,哪個較大。
if (arr[cmax] > arr[index])
}
經典排序演算法總結篇
首先回顧下各種排序的主要思路 一 氣泡排序 示例 public static void bublesort int a 氣泡排序主要思路是 通過交換使相鄰的兩個數變成小數在前大數在後,這樣每次遍歷後,最大的數就 沉 到最後面了。重複n次即可以使陣列有序。氣泡排序改進1 在某次遍歷中如果沒有資料交換,...
排序演算法總結一
排序在演算法中是比較基礎也是相當重要的一部分,在這裡將會把各種排序演算法那加以總結,並實現 桶排序 穩定,時間o nlogn 計數排序 穩定,時間o kn 基數排序 堆排序 穩定,時間o nlogn 註解 一般說快速排序是不穩定的,但事實上快速排序有穩定的實現方法,故在這裡認為快排也是穩定的 接下來...
排序 演算法篇
目錄 堆排序歸併排序 氣泡排序 快速排序 氣泡排序 構建最小堆 public static void makeminheap int a,int n 從i節點開始調整,n為節點總數 從0開始計算 i節點的子節點為 2 i 1,2 i 2 public static void minheapfixdo...