排序前後兩個相等的數相對位置不變,則演算法穩定;
排序前後兩個相等的數相對位置發生了變化,則演算法不穩定;
不穩定例項
時間複雜度分析
快速排序平均每次把問題劃分兩個子問題,其遞迴關係式可表示如下
t (n
)=2t
(n2)
+o(n
)t(n) = 2t() + o(n)
t(n)=2
t(2n
)+o
(n)其中o(n
)o(n)
o(n)
為一次劃分的時間複雜度,對比主定理a=2
a = 2
a=2,b=2
b=2b=
2,nlog
ba=n
log2
2=nn^_}=n^_}=n
nlogba
=nl
og22
=n,符合情況2,所以時間復
雜度o(
nlog
balo
gn)=
o(nl
ogn)
時間複雜度o(n^_}logn)=o(nlogn)
時間複雜度o
(nlo
gba
logn
)=o(
nlog
n)。在極端的情況下,每次只能劃分成乙個子問題,一邊乙個,另外一邊n−1
n-1n−
1個,遞推關係式退化成如下
t (n
)=t(
n−1)
+t(1
)+o(
n)t(n)=t(n-1)+t(1)+o(n)
t(n)=t
(n−1
)+t(
1)+o
(n)此時,時間複雜度為o(n
2)o(n^)
o(n2)。
應用利用快排思想尋找陣列中第k大(小)的數字;求陣列**現次數超過一半的數(時間複雜度o(n));
void
selectionsort
(int
*a,int n)
}}
不穩定例項
void
insertionsort
(int a,
int n)
a[j +1]
= key;
}}
void
merge
(int arr,
int l,
int m,
int r)
for(j =
0; j < n2; j++)
i =0, j =
0, k = l;
while
(i < n1 && j < n2)
else
k++;}
while
(i < n1)
while
(j < n2)
}void
mergesort
(int arr,
int l,
int r)
}
時間複雜度分析
歸併排序每次把問題劃分為兩個規模相等的子問題,子問題排好序後再合併。合併函式merge
時間複雜度為o(n
)o(n)
o(n)
,所以歸併排序遞迴表示式如下
t (n
)=2t
(n2)
+o(n
)t(n) = 2t() + o(n)
t(n)=2
t(2n
)+o
(n)根據主定理可以計算該時間複雜度為o(n
logn
)o(nlogn)
o(nlog
n)。因為不管元素在什麼情況下都要做這些步驟,所以該演算法最優時間複雜度和最差時間複雜度及平均時間複雜度都是一樣的。
void
heapify
(int arr,
int n,
int i)
}void
heapsort
(int arr,
int n)
}
時間複雜度:o (n
)+(n
−1)∗
o(lg
n)=o
(nlg
n)o(n) + (n-1)*o(lgn)=o(nlgn)
o(n)+(
n−1)
∗o(l
gn)=
o(nl
gn)其中
o (n
)o(n)
o(n)
: 建堆時間複雜度
( n−
1)o(
lgn)
(n-1)o(lgn)
(n−1)o
(lgn
) : 每次將堆頂和最後乙個元素交換後,調整堆時間複雜度為o(l
gn)o(lgn)
o(lgn)
,交換n−1
n-1n−
1次因為每次都要把根節點移到最後,所以假定陣列值是一樣的,很顯然原來的順序不能維持;
常用排序演算法穩定性 時間複雜度分析
1 選擇排序 快速排序 希爾排序 堆排序不是穩定的排序演算法,氣泡排序 插入排序 歸併排序和基數排序是穩定的排序演算法。2 研究排序演算法的穩定性有何意義?首先,排序演算法的穩定性大家應該都知道,通俗地講就是能保證排序前兩個相等的資料其在序列中的先後位置順序與排序後它們兩個先後位置順序相同。再簡單具...
常用排序演算法穩定性 時間複雜度分析
1 選擇排序 快速排序 希爾排序 堆排序不是穩定的排序演算法,氣泡排序 插入排序 歸併排序和基數排序是穩定的排序演算法。2 研究排序演算法的穩定性有何意義?首先,排序演算法的穩定性大家應該都知道,通俗地講就是能保證排序前兩個相等的資料其在序列中的先後位置順序與排序後它們兩個先後位置順序相同。再簡單具...
常用排序演算法穩定性 時間複雜度分析
1 選擇排序 快速排序 希爾排序 堆排序不是穩定的排序演算法,氣泡排序 插入排序 歸併排序和基數排序是穩定的排序演算法。2 研究排序演算法的穩定性有何意義?首先,排序演算法的穩定性大家應該都知道,通俗地講就是能保證排序前兩個相等的資料其在序列中的先後位置順序與排序後它們兩個先後位置順序相同。再簡單具...