《算法圖解》學習總結

最近在學習算法,選用的是《算法題解》這本書,作爲算法的入門書籍。爲了以後方便複習以及加強記憶,每次看完一章以後都會把知識點記錄到這個文章當中。本文的結構會參考《算法圖解》的目錄結構,方便自己記錄。在文章中,可能會有一些算法有LZ自己簡單實現的算法代碼,但部分算法沒有具體的代碼實現,因此僅供參考。

文章中的log​​​​​​指的都是log_2,算法速度用大O表示法來表示。


目錄

算法:

1、二分查找(折半查找)

2、選擇排序

3、快速排序

4、廣度優先搜索 

5、迪克斯特拉算法 

6、貪婪算法

7、K最近鄰算法(KNN)

文章相關知識點


算法:

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(log(n)

簡單代碼實現:

    /**
     * 用二分法查詢數據在數組中的位置,當數據存在時,返回數據所在角標,不存在時,返回-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(log(n^{^{2}})

簡單代碼實現:

    /**
     * 將一個無序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(log(n log n)

簡單代碼實現:

/**
     * 對數組進行從小到大排序
     *
     * @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的各個未曾訪問過的鄰接點,然後分別從這些鄰接點出發依次訪問它們的鄰接點,並使得“先被訪問的頂點的鄰接點先於後被訪問的頂點的鄰接點被訪問,直至圖中所有已被訪問的頂點的鄰接點都被訪問到。如果此時圖中尚有頂點未被訪問,則需要另選一個未曾被訪問過的頂點作爲新的起始點,重複上述過程,直至圖中所有頂點都被訪問到爲止。

 

5、迪克斯特拉算法 

使用場景:找出總權重最小的路徑。

注意事項:只適合有向無環圖,並且不能用於包含負權邊的圖。

具體思想:

(1)找出最便宜的節點,即可在短時間內前往的節點。

(2)對於該節點的鄰居,檢查是否有前往她們的更短路徑,如果有,就更新其開銷。

(3)重複這個過程,直到對圖中的每個節點都這麼做。

(4)計算最終路徑。

6、貪婪算法

使用場景:解決NP完全問題(沒有快速算法的問題),尋找局部最優解,企圖以這種方式獲取全局最優解

具體思想:對於一些NP完全問題,最佳的做法是使用近似算法,找到和最優解差不多的結果。

 

7、K最近鄰算法(KNN)

使用場景:對數據進行分類(編組)和迴歸(預測結果)

具體思想:對事物進行特徵抽取,轉換成一系列可比較的數字。

 

 


文章相關知識點

這裏是《算法圖解》中提到的額外的知識點,有助於瞭解和學習算法:

1、大O表示法含義

2、D&C(分而治之)原理

3、遞歸原理

4、內存工作原理

5、數組和鏈表結構

6、調用棧過程

7、散列表原理

8、歐幾里得定律

9、隊列和棧結構

10、判斷什麼是NP問題

11、動態規劃使用方法和侷限性

12、提到但沒介紹內容:B樹,紅黑樹,堆,伸展樹,反向索引,傅里葉算法,並行算法

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章