《演算法圖解》學習記錄------持續更新
最近在學習演算法,選用的是《演算法題解》這本書,作為演算法的入門書籍。為了以後方便複習以及加強記憶,每次看完一章以後都會把知識點記錄到這個文章當中。本文的結構會參考《演算法圖解》的目錄結構,方便自己記錄。在文章中,可能會有一些LZ自己簡單實現的演算法程式碼,僅供參考。
文章中的指的都是,演算法速度用大O表示法來表示。
目錄
演算法:
1、二分查詢(折半查詢)
使用場景:在一個有序的元素列表中,查詢某個資料所在的位置。
具體思想:
1.確定查詢範圍front=0,end=N-1,計算中項mid=(front+end)/2。
2.若a[mid]=x或front>=end,則結束查詢;否則,向下繼續。
3.若a[mid]<x,說明待查詢的元素值只可能在比中項元素大的範圍內,則把mid+1的值賦給front,並重新計算mid,轉去執行步驟2;若a[mid]>x,說明待查詢的元素值只可能在比中項元素小的範圍內,則把mid-1的值賦給end,並重新計算mid,轉去執行步驟2。
時間複雜度:O()
簡單程式碼實現:
/** * 用二分法查詢資料在陣列中的位置,當資料存在時,返回資料所在角標,不存在時,返回-1 * * @param array 被查詢的有序陣列 * @param value 要查詢的資料 * @return 查詢結果 */ public static int binary(int[] array, int value) { int low = 0; int high = array.length - 1; while (high >= low) { int mid = (low + high) / 2; if (array[mid] == value) { return mid; } else if (array[mid] > value) { high = mid - 1; } else { low = mid + 1; } } return -1; }
2、選擇排序
使用場景:將一個元素列表,按照一定的要求進行排序
具體思想:
1、從待排序元素列表中找到最小(或最大)的元素,放到有序陣列中末尾。
2、對剩餘的元素重複步驟1,直到待排序的元素列表中的元素全部放到有序陣列中。
時間複雜度:O()
簡單程式碼實現:
/** * 將一個無序int陣列從小到大排序 * * @param array 要排序的int陣列 * @return 查詢結果 */ public static int[] selectSort(int[] array) { int minIndex = 0; int temp = 0; for (int i = 0; i < array.length; i++) { //獲取要查詢無序陣列的第一個角標 minIndex = i; for (int j = i; j < array.length; j++) { //找到無序陣列的最小值角標,並儲存 if (array[minIndex] > array[j]) { minIndex = j; } } //將要查詢陣列第一個值與最小值交換,無序陣列長度減少,前面的都是有序陣列 temp = array[i]; array[i] = array[minIndex]; array[minIndex] = temp; } return array; }
3、快速排序
使用場景:將一個元素列表,按照一定的要求進行排序
具體思想:
1、選擇基準值。
2、將元素列表分為兩個子列表:小於基準值和大於基準值。
3、對這兩個子陣列再次進行步驟1-2操作
時間複雜度:O()
簡單程式碼實現:
/**
* 對陣列進行從小到大排序
*
* @param array 要排序的陣列
* @param low 要從陣列哪一位開始排序
* @param high 排序位置要截止到陣列的哪一位
*/
public static void quickSort(int[] array, int low, int high) {
//判斷陣列是否需要排序
if (low < high) {
//將元素列表分為兩個子列表:小於基準值和大於基準值,並返回基準值所在的位置
int middle = getMid(array, low, high);
//對小於基準值的陣列再次排序
quickSort(array, low, middle - 1);
//對大於基準值的陣列再次排序
quickSort(array, middle + 1, high);
}
}
/**
* 將陣列按照基準值分為大於基準值和小於基準值兩部分,並返回基準值所在的座標
*
* @param array 要排序的陣列
* @param low 要從陣列哪一位開始排序
* @param high 排序位置要截止到陣列的哪一位
* @return 基準值所在的角標
*/
public static int getMid(int[] array, int low, int high) {
//陣列的第一個作為基準值
int tmp = array[low];
//對陣列中的值進行遍歷
while (low < high) {
//從右往左找比基準值小的數
while (low < high && array[high] >= tmp) {
high--;
}
//將找到的比基準值小的數插在左端
array[low] = array[high];
//從左往右找比基準值大的數
while (low < high && array[low] < tmp) {
low++;
}
//將找到的比基準值大的數插在右端
array[high] = array[low];
}
//將基準值插到已經分好大小的陣列中間
array[low] = tmp;
//返回基準值目前所在的位置
return low;
}
4、廣度優先搜尋
使用場景:解決路徑最短問題。(1)從節點A出發,又到達節點B的路徑嗎?(2)從節點A出發,到達節點B的哪條路徑最短?
具體思想:從圖中某頂點v出發,在訪問了v之後依次訪問v的各個未曾訪問過的鄰接點,然後分別從這些鄰接點出發依次訪問它們的鄰接點,並使得“先被訪問的頂點的鄰接點先於後被訪問的頂點的鄰接點被訪問,直至圖中所有已被訪問的頂點的鄰接點都被訪問到。如果此時圖中尚有頂點未被訪問,則需要另選一個未曾被訪問過的頂點作為新的起始點,重複上述過程,直至圖中所有頂點都被訪問到為止。
文章相關知識點
這裡是《演算法圖解》中提到的額外的知識點,有助於瞭解和學習演算法:
1、大O表示法含義
2、D&C(分而治之)原理
3、遞迴原理
4、記憶體工作原理
5、陣列和連結串列結構
6、呼叫棧過程
7、散列表原理
8、歐幾里得定律
9、佇列和棧結構