日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

写给中学生的算法入门:学代码之前看这篇就够了

發布時間:2025/3/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 写给中学生的算法入门:学代码之前看这篇就够了 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

導讀:本文內容主要源自德語大學中發起的科普活動,初衷是讓高中生領會算法和計算機科學的奇妙與魅力。閱讀本文不需要任何關于算法和計算的預備知識。我們希望不僅學生,而且包括希望了解迷人的算法世界的成年人都能從本書中得到啟發與樂趣。


作者:Thomas Seidl,?Jost Enderle,?Wolfgang P. Kowalk,?Berthold V?cking

本文摘編自《無處不在的算法》,如需轉載請聯系我們




00 算法的應用


最近幾十年來許多技術創新和成果都依賴于算法思想,這些成果廣泛應用于科學、醫藥、生產、物流、交通、通信、娛樂等領域。高效的算法使得你的個人電腦得以運行新一代的游戲,這些復雜的游戲在幾年前可能都難以想象。


更重要的是這些算法為一些重大科學突破提供了基礎。例如,人類基因組圖譜解碼得以實現與新算法的發明是分不開的,這些算法能將計算速度提高幾個數量級。


算法告訴計算機如何處理信息,如何執行任務。算法組織數據,使得我們能有效地搜索。如果沒有聰明的算法,我們一定會迷失在互聯網這個巨大的數據叢林中。


同樣,如果沒有天才的編碼和加密算法,我們也不可能在網絡上安全地通信。天氣預報與氣候變化分析也依靠高效模擬算法。


工廠生產線和物流系統有大量復雜的優化問題,只有奇巧的算法能幫助我們解決。甚至當你利用GPS尋找附近的餐廳或咖啡館時,也要靠有效的最短路計算才能獲得滿意的結果。


并非像很多人認為的,只有計算機中才需要算法。在工業機器人、汽車、飛機以及幾乎所有家用電器中都包含許多微處理器,它們也都依賴算法才能發揮作用。例如,你的音樂播放器中使用聰明的壓縮算法,否則小小的播放器會因為存儲量不足而無法使用。


現在的汽車和飛機中有成百上千的微處理器,算法能幫助控制引擎,減少能耗,降低污染。它們還能控制制動器和方向盤,提高穩定性與安全性。不久的將來,微處理器可能完全替代人,實現汽車的全自動駕駛。目前的飛機已經能做到在從起飛到降落的全過程中無須人工干預。


算法領域最大的進步都來自美好的思想,它指引我們更有效地解決計算問題。我們面對的問題絕不局限于狹義的算術計算,還有很多表面上不是那么“數學化”的問題。例如:


  • 如何走出迷宮?

  • 如何分割一張藏寶圖讓不同的人分別保存,但只有重新拼合才可能找到寶藏?

  • 如何規劃路徑,用最小成本訪問多個地方?


這些問題極具挑戰,需要邏輯推理、幾何與組合想象力,還需要創造力才能解決。這些就是設計算法所需要的主要能力。




01 二分搜索


我新買的Nelly的唱片哪兒去啦?我那專橫的妹妹Linda有整潔癖,肯定是她將唱片又插進唱片架上了。我告訴她新買的唱片別插上去。這下我得在架子上的500張唱片中一張一張地找了,這該找到什么時候啊!


不過,走運的話也可能并不需要查看所有唱片就碰到了。但最壞的情況是Linda又把唱片借給朋友了,那得查完所有唱片才知道不在這里了,然后只好去聽廣播啦。


找找看吧!Aaliyah,AC/DC,Alicia Keys……嗯,Linda好像按字母順序給唱片排過序了。這樣的話我找Nelly的唱片就容易多了。


我先在中間試試。Kelly Family,這太偏左了,必須往右邊找。Rachmaninov,這又太偏右了,再往左一點兒……Lionel Hampton,右了點兒,但不遠了。Nancy Sinatra……Nelly,找到啦!


這倒很快!因為唱片已經排了序,我只要來回跳幾次就找到目標了!即使我要的唱片不在架子上,我也能很快發現。不過如果唱片很多,比如說10 000張,那可能得來回跳上幾百次吧。我很想知道如何計算次數。圖1-1給出了不同搜索方法的示意。


▲圖1-1 順序搜索與二分搜索圖示


1. 順序搜索


Linda從去年開始學習計算機科學;她應該有些書能告訴我答案。我看看,“搜索算法”可能有用。這里說了如何在一個給定集合(這里是唱片)中按照關鍵字(這里用藝術家的名字)找一個對象。我剛才的做法應該是“順序搜索”,又叫“線性搜索”。


就像我想的一樣,為了找一個關鍵字,平均得檢查一半的唱片。搜索的步數和唱片數成正比,換句話說,唱片數增加一倍,搜索時間也就增加一倍。


2. 二分搜索


我用的第二種技術好像有個特別的名字,叫“二分搜索”。給定要找的關鍵字以及排好次序的對象列表,搜索從中間那個對象開始,和關鍵字進行比較。如何中間那個對象就是要找的,搜索就結束了。


否則,按照要找的關鍵字是小于還是大于當前檢查的對象決定該向左還是該向右繼續搜索。接下來就是重復上面的過程。


如果找到了搜尋的對象,或者當前可能搜索的區間已經不能再切分了(也就是說如果表中有要找的對象,當前位置就該是目標應該在的位置),搜索就終止。我妹妹的書中有相應的程序代碼。


在這段代碼中,A表示一個“數組”,也就是由帶編號的對象(我們稱其為數組的元素)構成的數據列表,編號就像唱片在架子上的位置。例如,數組中第5個元素寫為A[5]。


如果我們的架子上放了500張唱片,我們要找的關鍵字是"Nelly",那就得調用BINARYSEARCH(rack, "Nelly", 1, 500)搜索要找的唱片所在位置。程序執行時,開始的left值為251,right值為375,以此類推。



3. 遞歸實現


在Linda的書中還有另外一個二分搜索算法。同樣的功能為什么需要不同算法呢?書上說第二種算法采用“遞歸方法”,那又是什么呢?


我再仔細看看……“遞歸函數是一種利用自身來定義或者調用自己的函數。”求和函數sum就是個例子。函數sum的定義如下:


sum (n) = 1 + 2 + … + n


也就是前n個自然數相加,所以,當n = 4,可得:


sum (4) = 1 + 2 + 3 + 4 = 10


如果我們想計算對于某個n的sum函數值,而且已經知道對于n-1的函數值,那只要再加上n就可以了:


sum (n) = sum (n-1) + n


這樣的定義式就稱為“遞歸步”。當要計算對于某個n的sum函數值時,我們還需要一個最小的n對應的函數值,這稱為奠基:


sum (1) = 1


按照遞歸定義,我們現在計算sum函數值的過程如下:


sum (4) = sum (3) + 4

= (sum (2) + 3) + 4

= ((sum (1) + 2) + 3) + 4

= ((1 + 2) + 3) + 4

= 10


二分搜索的遞歸定義是一樣的:函數在函數體中調用自己,而不是反復執行一組操作(那稱為循環實現)。



和前面一樣,A是要搜索的數組,key是要找的關鍵字,left和right分別是搜索區域的左右邊界。如果我們要在包含500個元素的數組rack中找Nelly,我們采用類似的函數調用BINSEARCHRECURSIVE(rack,"Nelly",1,500)。但這里不再通過程序循環使得搜索區域左右邊界逐步靠近,而是直接修改邊界值執行遞歸調用。實際執行的遞歸調用序列如下:


BINSEARCHRECURSIVE (rack, “Nelly”, 1, 500)

BINSEARCHRECURSIVE (rack, “Nelly”, 251, 500)

BINSEARCHRECURSIVE (rack, “Nelly”, 251, 374)

BINSEARCHRECURSIVE (rack, “Nelly”, 313, 374)

BINSEARCHRECURSIVE (rack, “Nelly”, 344, 374)

...


4. 搜索的步數


至此,我們仍然不知道要找到所需的對象究竟該執行多少搜索步。如果運氣好,一步就能找到。反之,如果要找的對象不存在,我們必須來回跳動直至對象應該處于的位置。


這樣就需要考慮究竟數組能夠被切為兩半多少次,或者反過來說,當執行了一定數量的比較操作后,究竟多少元素可以被確定是或者不是目標對象。


假設要找的對象確實在表中,一次比較可以確定2個元素,兩次比較可以確定4個元素,三次比較就能確定8個元素。因此執行k次比較操作能夠確定2·2·…·2(k次)= 2k個元素。由此可知10次比較可以確定1024個元素,20次比較能確定的元素超過100萬個,而30次比較能確定的元素多達10億個以上。


如果目標對象不在數組中,則需要多比較一次。為了能根據元素個數確定比較次數,我們需要逆運算,也就是2的乘冪的反函數,即“以2為底的對數”,記作log2。一般地說:


假設a = bx,則x = logba


對于以2為底的對數,b = 2:


20 = 1, log2 1 = 0

21 = 2, log2 2 = 1

22 = 4, log2 4 = 2

23 = 8, log2 8 = 3

.

.

. .

.

.

210 = 1 024, log2 1 024 = 10

.

.

. .

.

.

213 = 8 192, log2 8 192 = 13

214 = 16 384, log2 16 384 = 14

.

.

. .

.

.

220 = 1 048 576, log2 1 048 576 = 20


因此,若k次比較操作能確定N(= 2k)個元素,那么對于含N個元素的數組,二分搜索需要執行log2 N = k次比較操作。如果我們的架子上放了10 000張唱片,我們需要比較log2 10 000≈13.29次。因為不可能比較“半次”,需要的次數為14。


要想進一步減少二分搜索需要的步數,可以在搜索過程中不是簡單地選擇中間元素進行比較,而是嘗試在搜索區域內更準確地“猜測”可能的位置。


假設在已排序的唱片中搜索的對象名按字母順序更靠近區域開始處,例如找Eminem,顯然選擇前部的某個位置進行比較更好些。反之,要找“Roy Black”,從靠后的地方開始更合理。


若要更好地改進,就得考慮每個字母可能出現的頻率,例如首字母是D或S的藝術家通常比首字母是X或Y的更常見。


5. 猜數游戲


今晚我要考考Linda,讓她猜1到1000之間的某個數。只要上課沒睡覺,她就應該能最多通過10個“是/否”的問題得到結果。(圖1-2顯示如何只問4個問題就猜出1到16之間的某個數。)


為了避免反復問那些“是小于某個數嗎?”或者“是大于某個數嗎?”那樣乏味的問題,我們可以選擇問“是奇數嗎?”或“是偶數嗎?”。因為一個回答就可以讓我們排除一半的可能性。


類似的問題包括“十(百)位數是奇(偶)數嗎?”,像這樣的問題同樣可以使搜索空間(大致)縮小一半。不過要確認考慮了所有可能的數,我們還得回到通常采用的減半方法(那些已經被排除的數實際上已考慮在內)。


如果采用二進制表示數,這個過程甚至會更簡單。十進制系統是用“10的乘冪的和”的形式表示數,例如:


107 = 1·102 + 0·101 + 7·100

= 1·100 + 0·10 + 7·1


▲圖1-2 在1~16范圍內猜出某個數的圖示


而在二進制系統中數是用“2的乘冪的和”的形式表示的:


107 = 1·26 + 1·25 + 0·24 + 1·23 + 0·22 + 1·21 + 1·20

= 1·64 + 1·32 + 0·16 + 1·8 + 0·4 + 1·2 + 1·1


因此107的二進制表示為1101011。要猜出一個二進制表示的數只要知道它最多多少位就足夠了。位數用以2為底的對數很容易計算。如果猜一個1到1000之間的數,可以計算如下:


log2 1000≈9.97(向上取整)


也就是說共有10位。因此問10個問題足夠了:“第1位數是1嗎?”“第2位數是1嗎?”“第3位數是1嗎?”等等。最后所有位都知道了還必須轉換為十進制數,用一個掌上的計算器就能解決了。



02 插入排序


我們要把書架上所有的書按照書名排序,這樣需要哪本書時很快就能找到。


如何快速地實現排序呢?我們可以有幾種不同的想法。例如我們可以依次查看每本書,一旦發現兩本緊挨著的書的次序不對就交換一下位置。這種想法能行,因為最終任何兩本書的先后都不會錯,但這平均要花費太長的時間。


另一種想法是先找出書名最“小”的那本書放在第一個位置,然后在剩下的書中再找出最“小”的放在緊挨著的后面位置,以此類推直到所有書都放在了正確的地方。這種想法也能行;但是由于大量有用的線索沒有利用,多花費了許多時間。下面我們試試其他的想法。


下面的想法似乎比上面討論的更加自然。第一本書自然是排好的。接下來我們拿第一本書的書名與第二本書的書名做比較,如果次序不對就交換兩本書的位置。然后我們看下一本書在前面已經排好序的部分中應該放在什么位置。


這可以反復進行直到為所有的書安排了正確的位置。因為前面的書排序時提供的信息可供后面使用,這個方法應該效率高一些。


現在把這個算法再細細看一下。第一本書單獨考慮可以看作排好了序。我們假設當前考慮的書是第i本書,而它左邊所有的書都已排好序了。要將第i本書加入序列中,我們首先查找它正確的位置,隨后將書插入即可;為此要將在正確位置右邊的所有書向右移動一個位置。


接下來對第i + 1本書重復以上過程,以此類推直到所有的書放到了正確位置。這個方法能快速產生正確結果,特別是如果我們采用第1章介紹的二分搜索尋找正確插入位置則效果更明顯。


我們現在來看看對任意數量的書,這個直觀的方法如何實現。為了描述起來簡單一些,我們用數字代替書名。


圖2-1中左邊的5本書(1,6,7,9,11)已經排好序,而書名為5的書位置不正確。為了將5放入正確位置,首先與11交換位置,再與9交換位置,以此類推直到5到達正確位置。然后我們再處理書名為3的書,同樣通過與左側的書交換來到達正確位置。顯然最終所有的書都會放到正確的地方(見圖2-2)。


▲圖2-1 前5本書已排好序


▲圖2-2 書名為“5”的書移動到正確位置


以下是算法的代碼。這里使用數組A,其元素標號為1,2,3,…。A[i]表示數組中第i個元素的值。給n本書排序使用長度為n的數組,元素A[1],A[2],A[3],…,A[n-1],A[n]存放所有的書名。



現在考慮算法執行花費的時間。我們考慮最壞的情況,所有書放置的位置正好與期望的次序相反,即書名最小的在最后的位置上,而書名最大的卻在最前面的位置上。


我們的算法讓第1本書與第2本書交換位置,第3本書要和前兩本書中每一本交換位置,第4本書則要和前面3本書中每一本交換位置,以此類推,最后的一本書得和前面n-1本書中的每一本交換位置。交換的總次數是:


1+2+3+...+(n-1)=n(n-1)/2


利用圖2-3很容易推導出上述公式。整個矩形中含n·(n-1)個單元格,其中一半用于比較與交換。圖中顯示的是絕對的最壞情況。考慮平均情況,我們可以假設只需要一半的比較與交換。


如果開始時書就幾乎是排好序的,需要的工作量會少很多;最好的情況是開始時所有的書都在正確的位置上,那只需要進行n-1次比較即可。


▲圖2-3 計算交換次數


你也許會看出算法還可以更簡潔些。不用交換相鄰的兩本書,而是將多本書向右移動,使得需要的插入位置空出來。如果2-4所示。


原來的k次兩兩置換操作,現在可以用k + 1次移動一本書的操作替代。算法修改如下:



▲圖2-4 計算交換次數


盡管在串行的計算機上此算法排序效率不高,但它的實現非常簡單,所以當需要排序的對象數量不太大,或者可以假設多數對象次序不錯的情況下還是會經常使用插入排序算法。要對大量對象進行排序就會使用其他算法,如mergeSort和quickSort。那些算法理解起來會難一些,實現也更復雜。


關于作者:本書共有66位作者,主要來自德國、瑞士。由貝特霍爾德·弗金(Berthold V?cking)、赫爾穆特·阿爾特(Helmut Alt)、馬丁·迪茨費爾賓格(Martin Dietzfelbinger)、呂迪格·賴舒科(Rüdiger Reischuk)、克里斯蒂安·沙伊德勒(Christian Scheideler)、黑里貝特·沃爾默(Heribert Vollmer)、多蘿西婭·瓦格納(Dorothea Wagner)領銜編著。


本文摘編自《無處不在的算法》,經出版方授權發布。


延伸閱讀《無處不在的算法

點擊上圖了解及購買

轉載請聯系微信:togo-maruko


推薦語:杰出計算機教育家南京大學陳道蓄教授翻譯并推薦,啟蒙學生對計算機科學興趣、提升計算思維素養的入門讀本。



據統計,99%的大咖都完成了這個神操作



更多精彩


在公眾號后臺對話框輸入以下關鍵詞

查看更多優質內容!


PPT?|?報告?|?讀書?|?書單

大數據?|?揭秘?|?人工智能?|?AI

Python?|?機器學習?|?深度學習?|?神經網絡

可視化?|?區塊鏈?|?干貨?|?數學


猜你想看


  • 機器學習重大挑戰:壞數據和壞算法正在毀掉你的項目

  • 違背常識、顛覆認知,終于有人把薛定諤的貓講明白了

  • 干貨:用Python進行數據清洗,這7種方法你一定要掌握

  • 極度燒腦+驚人發現:4個顛覆你世界觀的量子理論實驗



Q:?這些技能你都掌握了嗎

歡迎留言與大家分享

覺得不錯,請把這篇文章分享給你的朋友

轉載 / 投稿請聯系:baiyu@hzbook.com

更多精彩,請在后臺點擊“歷史文章”查看

點擊閱讀原文,了解更多

總結

以上是生活随笔為你收集整理的写给中学生的算法入门:学代码之前看这篇就够了的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。