本文主要是通過通俗易懂的演算法和自然語言, 向大家介紹基礎的計算機排序演算法和查詢演算法, 還有一些作為一名程式猿應該知道的名詞, 資料結構, 演算法等等. 但是僅僅止於介紹, 因為本人能力不足, 對一些高階的演算法和資料結構理解不夠通透, 所以也不作太多的深入的剖析… demo都在我的github中能找得到。
同樣的, 通過最近面試實習生的機會, 把一些基礎都撿起來, 鞏固鞏固, 同時如果能幫助到大家, 那也是極好的. 廢話不多說, 入正題吧。
ps:基數排序的複雜度中, r代表關鍵字的基數, d代表位數, n代表關鍵字的個數. 也就是說,基數排序不受待排序列規模的影響。
演算法複雜度 : 這裡表中指的是演算法的時間複雜度, 一般由o(1), o(n), o(logn), o(nlogn), o(n²), …, o(n!). 從左到右複雜度依次增大, 時間複雜度是指在多少時間內能夠執行完這個演算法, 常數時間內呢, 還是平方時間還是指數時間等等。
還有個概念叫空間複雜度, 這就指的是執行這個演算法需要多少額外的空間。 (源陣列/鍊錶所佔的空間不算)
穩定性 : 演算法的穩定性體現在執行演算法之前,若a = b, a在b的前面,若演算法執行完之後a依然在b的前面, 則這個演算法是穩定的, 否則這個演算法不穩定
選擇排序
oid selectsort(int array, int count)
}// 交換元素
int temp = array[index];
array[index] = array[i];
array[i] = temp;}}
氣泡排序
原理:每次對比相鄰兩項的元素的大小,不符合順序則交換
原理:每次從無序區中找出最小的元素, 跟無序區的第乙個元素交換
void bubblingsort(int array, int count)}}
}
插入排序
原理:每次將乙個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子串行中的適當位置,直到全部記錄插入完成為止。
void insertsort(int array, int count)
if (j != i-1)
// 將array[i]放入合適的位置
array[k+1] = temp;}}
}
希爾排序
其實就是分組插入排序, 也稱為縮小增量排序. 比普通的插入排序擁有更高的效能.
演算法思想 : 根據增量dk將整個序列分割成若干個子串行. 如dk = 3, 序列1, 7, 12, 5, 13, 22 就被分割成1, 5, 7, 13和12, 22, 在這幾個子串行中分別進行直接插入排序, 然後依次縮減增量dk再進行排序, 直到序列中的元素基本有序時, 再對全體元素進行一次直接插入排序. (直接插入排序在元素基本有序的情況下效率很高)
void shellsort(int array, int count)
// 每組第乙個元素為最小的元素
array[k + dk] = temp;}}}}}
歸併排序
原理 : 歸併排序是把序列遞迴地分成短序列,遞迴出口是短序列只有1個元素(認為直接有序)或者2個序列(1次比較和交換),然後把各個有序的段序列並成乙個有序的長序列,不斷合併直到原序列全部排好序。
void merge(int array, int temp, int start, int middle, int end) else
}// 插完之後看誰沒插完就繼續插誰
while(i <= m) temp[k++] = array[i++];
while(j <= n) temp[k++] = array[j++];
// 把temp的元素copy回array中
for (int i = 0; i < k; i++) array[start + i] = temp[i];
}void msort(int array, int temp, int start, int end)
}void mergesort(int array, int count)
堆排序
•二叉堆的定義
◾二叉堆是完全二叉樹或者是近似完全二叉樹。
•二叉堆滿足二個特性:
◾父結點的鍵值總是大於或等於(小於或等於)任何乙個子節點的鍵值。
◾每個結點的左子樹和右子樹都是乙個二叉堆(都是最大堆或最小堆)。
大頂堆:父結點的鍵值總是大於或等於任何乙個子節點的鍵值
小頂堆:父結點的鍵值總是小於或等於任何乙個子節點的鍵值
演算法思想:堆排序 = 構造堆 + 交換堆末尾元素與根結點 + 刪除末尾結點 + 構造堆 + 交換…依次迴圈, 由於根結點必定是堆中最大(最小)的元素, 所以刪除出來的元素序列也必定是公升序(降序)的.
void minheapfixdown(int array, int i, int count)
array[i] = temp;void heapsort(int array, int count) }
快速排序
演算法思想 : 先從數列中取出乙個數作為基準數 -> 將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊 -> 再對左右區間重複第二步,直到各區間只有乙個數
int quicksortpartition(int array, int start, int end)
// 從左往右找第乙個大於哨兵的元素
while(i < j && array[i] <= sentry) i++;
// 找到了
if (i < j)
}// 把哨兵放到i == j的位置上
array[i] = sentry;
// 返回哨兵的位置
return i;
void quicksort(int array, int start, int end)
void quicksortentry(int array, int count)
基數排序
基數排序的演算法複雜度不會因為待排序列的規模而改變. 基數排序又稱為桶排序. 基數排序有3個重要概念 :
•r : 關鍵字的基數, 指的是關鍵字k的取值範圍, 十進位制數的話, k=10
•d : 位數
•n : 關鍵字的個數
這裡給個例子, 沒有**.
例如一組序列121 83 17 9 13
先根據個位數排序
121 83 13 17 9
再根據十位數排序
9 13 17 121 83
再根據百位數排序
9 13 17 83 121
由於沒有千位數, 所以演算法結束
ps : 需要注意的是, 基數排序每一輪排序所採用的演算法必須是穩定的排序演算法,
也就是說, 例如13和17的十位數均為1, 但是由於個位數排序的時候13是在17的前面的,
所以十位數排序過後13也必須在17的前面.
計算機 演算法
演算法 計算機的指令執行可以通過資料流程圖來表示,具體的資料處理則需要用到演算法。algorithm,演算法定義 被明確定義的有限個規則的集合,用於根據有限的步驟解決問題 計算機所執行的由程式表示的演算法必須是由機械的步驟所構成。因此產生了機械解決問題的 典型演算法 典型演算法 主要有輾轉相除法,埃...
計算機相關演算法
1.氣泡排序 氣泡排序演算法的運作如下 從後往前 比較相鄰的元素。如果第乙個比第二個大,就交換他們兩個。對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。針對所有的元素重複以上的步驟,除了最後乙個。持續每次對越來越少的元素重複上面的步驟,直到沒有任何一...
計算機視覺演算法
講了乙個最小二乘法問題 存在四個不在一條直線上點,擬合一條直線,使這條直線能夠 誤差最小的穿過這四個點 雖然還不知道具體怎麼解。引申到矩陣的最小二乘法 有三個矩陣a,b,c,a為4 2,c為4 1,a b c.求b矩陣 求b,a矩陣是乙個非奇異矩陣,不可逆,所以讓a轉置左乘a構成滿秩矩陣c,可得b等...