03.14 瞭解一下“算法”,每個人都要掌握的編程知識

假設我們有一個難題需要解決,那怎麼解決呢?解決的步驟怎樣呢?如果有一樣東西能把這個解決這個難題的步驟描述出來,那就叫做這個問題的算法。

你看,如果我們學習算法的話其實學習的是解決問題的步驟,無論我們從事哪個行業學一下算法都是很有幫助的。

瞭解一下“算法”,每個人都要掌握的編程知識

算法解決問題的步驟

01 算法概念的理解

瞭解一下“算法”,每個人都要掌握的編程知識

算法可以很複雜也可以很簡單

算法(Algorithm)是指解題方案的準確而完整的描述,是一系列解決問題的清晰指令,算法代表著用系統的方法描述解決問題的策略機制。

為什麼算法是解題方案的準確、完整的描述,而且還要清晰的指令呢?因為絕大多數算法最終需要轉換成計算機程序給計算機執行的,而計算機是比較死板的。更直白地講,算法呢大多數時候是充當了人和計算機之間的一種“翻譯”的角色。

那麼我們用什麼方法或者是工具來準確、完整、清晰的描述解題方案呢?也就是說,我們用什麼方法來描述算法呢?

給人看的算法呢,經常採用三種方式來描述它:

  1. 自然語言。所謂自然語言就是人類的語言,我們人類語言最大的特點就是不嚴謹,同樣一句話不同的語境、不同的人可能會有不同的理解,這和算法的定義是背道而馳的。所以又有了下面兩種算法描述方法。
  2. 流程圖,N-S圖。又稱程序框圖,用一組統一規定的標準符號描述程序運行具體步驟的圖形表示。這是一種非常好的算法描述方法,一圖勝千言。我們做02典型算法的例子裡會介紹。
  3. 偽代碼。一種非正式的,類似於英語結構的,用於描述模塊結構圖的語言
瞭解一下“算法”,每個人都要掌握的編程知識

流程圖的符號描述

瞭解一下“算法”,每個人都要掌握的編程知識

一段求三個數中最大數的偽代碼

02 一個典型算法的例子

其實我們碰到的很多問題,在不同的時間、不同的地點可能已經有另外的一些人碰到過很多很多次了。所以呢,就有很多很經典的算法,我們如果認真的研究一下這些算法,你會覺得比打遊戲打怪升級還更有意思。比如下面這張圖裡幾種常見的排序算法,所謂排序算法就是給計算機一組雜亂無章的數,讓它幫我們從小到大或者從大到小排列起來。

排序算法最常見的應用就是,期末考試的時候我們老師把每個同學的成績都輸入給計算機,計算機能幫我們把這些成績排個序。想象一下,如果是全國統考的高考,全國那麼多考生的成績排序,如果是人工排的話那得多大的工作量?光中午管盒飯也不老少啊!

瞭解一下“算法”,每個人都要掌握的編程知識

常見的幾種經典排序算法

我們以上圖中的第一種冒泡排序為例來說明一下算法,及其描述。

如果我們用自然語言來描述冒泡排序是這樣的:

  1. 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
  2. 對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最後一對。在這之後,最後的元素應該會是最大的數。
  3. 針對所有的元素重複以上的步驟,除了最後一個。
  4. 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。

你如果看上面這段名字可能有點懵逼,如果帶入一個問題場景來理解冒泡排序可能會容易的多。

比如說,我們有一組10個同學到操場集合站成一列,這個時候體育老師來了說:“大家按照身高從低到高排好!” 那怎麼排列呢?那這個時候呢就可以這樣來看:

  1. 從第一個開始比較相鄰的兩個同學,如果第一個同學比第二個同學高,那麼他們換一下位置。
  2. 第一個和第二個比完(可能要交換位置)之後呢,那麼第二個就肯定比第一個高了;這個時候再把第二個和第三個比較,如果還比第三個高,那麼再和第三個也交換一下位置。這樣一直比到第10個,那麼經過這麼一輪的比較之後,站在第10個的同學肯定就是所有同學裡面最高的了。
  3. 然後再用步驟1、2同樣的方法來對前面的9個同學操作,那第9個同學又變成剩下的9個裡面最高的了。
  4. 然後再對剩下的8個同學進行類似操作,然後是剩下的7個。。。一直到最後一個,這樣一輪又一輪地操作之後就把這10個同學從矮到高拍好了。

如果這樣的冒泡算法用流程圖來表示,是怎樣的呢?

瞭解一下“算法”,每個人都要掌握的編程知識

一個100個數的數組的冒泡排序

流程圖呢,其實是計算機專業的或者相近專業的人才看的東東。普通人要想看明白它呢,也很簡單。首先,找到“開始”,然後順著箭頭一路向下,如果碰到一個菱形就是一個分支,這個稜形裡面呢是一個條件,所謂條件就是滿足條件結果為真、不滿足為假,然後從稜形出來就要根據這個條件的取值選擇走哪條,如果是走回頭路的話就變成了一個循環,所以那你就帶著一個值慢慢跟著箭頭走,很容易搞明白。

03 怎樣評價算法的好壞?

俗話說“條條大路通羅馬”,但是呢並不是每條路都那麼好走的。有些路比較好找,但是需要走的時間長;有些路可以很快到達,但是很難走;有些路理論上能到達目的地,但是實際上幾乎相當於死路走不通。這樣的話呢,不同的衡量標準下呢這不同的路就有了好壞之分。

那麼解題的算法也是一樣,同一個問題可能有很多個算法,就像我們在02裡看到的排序算法。那麼,這麼多算法,我們有沒有什麼標準可以評價他們的好壞呢?答案是肯定的。

主要從幾個方面來衡量一個算法的優劣:

  1. 時間複雜度,可以粗暴地理解為運行這個算法所需要的時間;
  2. 空間複雜度,可以粗暴地理解為運行這個算法佔用的計算機(或手機之類的)內存大小,就是手機發燙不發燙;
  3. 正確性,這個就很好理解了;
  4. 可讀性,對於一些簡單問題的算法別整的像相對論那麼難理解;
  5. 健壯性,就是說如果我們給這個算法的輸入條件出錯了,這個算法會不會出錯,也叫容錯率。就好比前面對學生按高矮排序的時候,突然插入一個其它班的同學、或者跑過來一條小狗狗,算法有沒有考慮到這些情況。

好了,關於算法的理解入門,石頭就說這麼多了。


分享到:


相關文章: