關於氣泡排序和二分查詢
阿新 • • 發佈:2020-12-15
關於氣泡排序和二分查詢的一些個人看法
1. 氣泡排序
冒牌排序為什麼叫氣泡排序呢?是因為每次都會有一個較小的數不斷往陣列前方走(小到大排序),如同一個泡泡上升的過程,因此我們稱之為氣泡排序。先貼一下程式碼:
void Bubble_sort()
{
for(int i = 1;i < n;i ++ )
{
for(int j = 1;j < n;j ++ )
{
if(a[j] > a[j + 1])
{
swap(a[j],a[j + 1]);
}
}
}
}
我們每次都選取數列中的第一個元素\(a[j]\)往後比較,若\(a[j+1]\)
2. 二分查詢(\(a\)陣列為單調遞增數列)
二分查詢是確定一個元素在數列中的位置的演算法。什麼樣子的陣列能使用二分查詢呢?不如來看看二分查詢的程式碼:
int equal_dict(int x) { while(l < r) { int mid = (l + r) >> 1; if(a[mid] >= x) r = mid; else l = mid + 1; } return a[l]; }
先說結論:具有單調性的陣列才可以進行二分查詢。每次我們都有一個\(l\)和\(r\),來表示我們要查詢的範圍,\(mid\)為\(l\),\(r\)的中間值。如果以mid為下標的數大於了目標值\(x\),則下標為\(mid\)的數以後都是大於\(x\)的,所以\(x\)不可能位於\(mid\)右側,所以我們就選擇\(mid\)的左側,這個區間一定是\(x\)所在的區間。小於同理。如果數列不是有序的,則不能進行縮小區間的操作,無法找到\(x\)的位置。
二分演算法充分利用了元素間的次序關係,採用分治策略。由於每次區間長度折半,所以時間複雜度為\(O(log_{2}{n})\)。發明二分演算法的大佬Knuth說,思路很簡單,細節是魔鬼。二分的細節很是重要,據說只有10%的程式設計師能寫對二分。所以二分要掌握自己的一套寫法,練熟練會即可。
寫在後面
排序演算法有很多種,大致可以分為以下三類:
- 氣泡排序、插入排序、選擇排序
- 堆排序、歸併排序、快速排序
- 計數排序、基數排序、桶排序
前兩類都是基於比較的排序演算法,第一類排序時間複雜度為\(O(n^2)\),第二類排序時間複雜度為\(O(nlog_n)\),資訊理論以證明,基於比較的排序演算法的時間複雜度下界為\(O(nlog_n)\),第二類演算法已經是最優的基於比較的排序演算法了
第三類演算法換了一種思路,它們不直接比較大小,而是對被排序的數值採取按位劃分,分類對映等處理方式,其時間複雜度不僅與\(n\)有關,還與數值的大小範圍\(m\)有關。