氣泡排序(bubble sort)
插入排序(insertion sort)
選擇排序(selection sort)
解答開篇
本篇部落格將會總結一下冒泡、插入、選擇排序,思考乙個問題就是,插入排序和氣泡排序的時間複雜度都是o(n^2),但是為何在實際軟體開發中更傾向於選擇插入排序?
分析排序演算法的執行效率,主要是從以下幾個方面:
最好情況、最壞情況、平均情況複雜度;
時間複雜度的係數、常數、低階;
比較次數和交換次數;
對於排序演算法的空間複雜度,引入乙個原地排序(sorted in place)的概念,原地排序演算法就是空間複雜度為o(1)的排序演算法;
穩定性,是指待排序的序列中存在值相等的元素,經過排序之後,想等元素之間原有的先後順序不變;
氣泡排序每次只會操作相鄰的兩個資料,看是否滿足大小關係,不滿足就呼喚,一次氣泡排序就會至少讓乙個元素移動到它應該在的位置上,重複n次,就完成了n個資料的排序工作。
上圖為一次氣泡排序的過程,其實氣泡排序還是可以優化的。當某次冒泡操作沒有資料可以交換時,說明已經達到完全有序,不用在執行後序的冒泡操作。
**如下:
public
void
bubblesort
(int
a,int n)}if
(!flag)
break
;//沒有資料交換,提前退出
}}
首先將陣列中的資料分為兩個區間,已排序區間和未排序區間。初始已排序區間只有乙個元素,就是陣列的第乙個元素;插入排序演算法的核心是從未排序區間中選取元素,在已排序區間中找到合適的插入位置將其插入,並保證已排序區間中的資料一直有序,直到未排序的區間中的元素為空;下圖是插入排序的過程;
//插入排序,a表示陣列,n表示陣列大小
public
static
void
insertionsort
(int
a ,int n)
else
} a[j+1]
= value;
}}
選擇排序演算法類似插入排序,將陣列分為已排序區間和未排序區間,但是每次是從未排序區間中找到最小的元素,將其放到已排序的區間的末尾;
//選擇排序,a表示陣列,n表示陣列大小
public
static
void
selectionsort
(int
a,int n)
}//交換
int tmp = a[i]
; a[i]
= a[minindex]
; a[minindex]
= tmp;
}}
從**實現上來看,氣泡排序的資料交換要比插入排序的資料移動要複雜,氣泡排序需要3個賦值操作,而插入排序只需要1個。我們來看這段操作:
氣泡排序中資料的交換操作:
if (a[j] > a[j+1])
插入排序中資料的移動操作:
if (a[j] > value) else
我們把執行乙個賦值語句的時間粗略地計為單位時間(unit_time),然後分別用氣泡排序和插入排序對同乙個逆序度是k的陣列進行排序。用氣泡排序,需要k次交換操作,每次需要3個賦值語句,所以交換操作總耗時就是3*k單位時間。而插入排序中資料移動操作只需要k個單位時間雖然氣泡排序和插入排序在時間複雜度上是一樣的,都是o(n2),但是如果我們希望把效能優化做到極致,那肯定首選插入排序。
資料結構與演算法之美 排序(上)
開篇問題的解答請放到最後再看噢 雖然氣泡排序和插入排序演算法的時間複雜度都是o n2 氣泡排序涉及到元素的交換,插入排序涉及到元素的移動,交換次數和移動次數都是相同的,都是原始序列的逆序度。在氣泡排序中,元素的交換要三次賦值語句,而插入排序中元素的移動只需要一次賦值語句。所以若考慮到效能優化到極致,...
資料結構與演算法之排序(上)
對於冒泡這個排序演算法,相信大家都不陌生,所以我們更加深入的來看一下這個演算法,討論一下他的時間複雜度,最好情況是當所有元素都按公升序排列好了,這個時候的時間複雜度是o n 多少個元素就比較了多少次。為了不讓排序無腦的進行下去,我們加了乙個flag標記,排好序便會自動退出。最壞的情況下,都是逆序排的...
資料結構與演算法之美
什麼是資料結構?什麼是演算法 狹義重點 複雜度分析 方法 邊學邊練,適度刷題 複雜度分析 時間複雜度 常見時間複雜度 非多項式量級 非常低效的演算法 空間複雜度 漸進空間複雜度,表示演算法的儲存空間和資料規模的增長關係 最好情況時間複雜度 理想情況的時間複雜度 最壞情況時間複雜度 最糟糕的情況下的時...