排序的穩定性:
如果兩個元素的數值相等,那麼在排序之後兩者的相對位置不會發生變化(a在b前面,排序之後,a還是在b前面),這樣的特性稱之為「穩定」。
經典例子:
穩定的排序:氣泡排序、插入排序、歸併排序等
不穩定的排序: 快速排序、堆排序等
不穩定排序,以快速排序為例做演示,他的核心思想是分治:
1、 先從序列中取出乙個數作為basic number。
2、將比此數大的元素放到它的右邊,小於或等於它的元素放到它的左邊。
3、對左右區間重複第二步,直到各區間只有乙個數為止。
實驗例子:
建立tree結構體型別,裡面有編號,樹的高度。以高度為基準進行排序。
#include #include #include using namespace std;
struct tree
friend ostream& operator << (ostream &out, tree &object)
};int main()
vec.push_back( tree(1+i, randomheight) );
}for(auto it: vec)
cout << endl;
sort( vec.begin(), vec.end(),
//氣泡排序的分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。
(const tree t1, const tree t2)->bool
);for(auto it: vec)
cout << endl;
}
output:
(1, 10) (2, 0) (3, 30) (4, 0) (5, 50) (6, 0) (7, 70) (8, 0) (9, 90) (10, 0)
(10, 0) (8, 0) (6, 0) (4, 0) (2, 0) (1, 10) (3, 30) (5, 50) (7, 70) (9, 90)
height為0的元素相對位置發生了變化。
穩定的排序,以氣泡排序為例,接著上面的場景:
for( int i = 0; i < 10; ++i )
}}
output:
(1, 10) (2, 0) (3, 30) (4, 0) (5, 50) (6, 0) (7, 70) (8, 0) (9, 90) (10, 0)
(2, 0) (4, 0) (6, 0) (8, 0) (10, 0) (1, 10) (3, 30) (5, 50) (7, 70) (9, 90)
在這裡,c++提供了結構體拷貝建構函式,所以swap得以順利work。
下面的swap實現版本來自
template inline _libcpp_inline_visibility
#ifndef _libcpp_has_no_advanced_sfinae
typename enable_if
<
is_move_constructible<_tp>::value &&
is_move_assignable<_tp>::value
>::type
#else
void
#endif
swap(_tp& __x, _tp& __y) _noexcept_(is_nothrow_move_constructible<_tp>::value &&
is_nothrow_move_assignable<_tp>::value)
排序穩定性
這幾天筆試了好幾次了,連續碰到乙個關於常見排序演算法穩定性判別的問題,往往還是多選,對於我以及和我一樣拿不準的同學可不是乙個能輕易下結論的題目,當然如果你筆試之前已經記住了資料結構書上哪些是穩定的,哪些不是穩定的,做起來應該可以輕鬆搞定。本文是針對老是記不住這個或者想真正明白到底為什麼是穩定或者不穩...
排序的穩定性
這幾天筆試了好幾次了,連續碰到乙個關於常見排序演算法穩定性判別的問題,往往還是多選,對於我以及和我一樣拿不準的同學可不是乙個能輕易下結論的題目,當然如果你筆試之前已經記住了資料結構書上哪些是穩定的,哪些不是穩定的,做起來應該可以輕鬆搞定。本文是針對老是記不住這個或者想真正明白到底為什麼是穩定或者不穩...
排序的穩定性
穩定性定義 排序前後兩個相等的數相對位置不變,則演算法穩定。穩定性得好處 從乙個鍵上排序,然後再從另乙個鍵上排序,第乙個鍵排序的結果可以為第二個鍵排序所用。氣泡排序 小的元素往前調或者把大的元素往後調 比較是相鄰的兩個元素比較,交換也發生在這兩個元素之間 因為相等的元素不會進行交換,所以穩定 插入排...