《資料結構與演算法JavaScript描述》選讀:為什麼要學習資料結構和演算法

群峰發表於2014-04-23

在過去的幾年中,得益於Node.js和SpiderMonkey這樣的平臺,JavaScript越來越多地被用於伺服器端程式設計。鑑於JavaScript語言已經走出了瀏覽器,程式設計師發現他們需要更多傳統語言,比如C++和Java提供的工具。這些工具包括經典的資料結構,如連結串列、棧、佇列、圖等,也包括經典的排序和查詢演算法。本書即討論了在使用JavaScript進行伺服器端程式設計時,如何實現這些經典的資料結構和演算法。

JavaScript程式設計師會發現本書很有用,因為本書討論了在JavaScript語言的限制之下,如何實現經典的資料結構和演算法。這些限制包括:陣列即物件、無處不在的全域性變數、基於原型的物件模型等。JavaScript作為一種程式語言,名聲有點“不大好”,但是本書展示瞭如何使用JavaScript語言中“好的一面”去實現高效的資料結構和演算法。

為什麼要學習資料結構和演算法

我假設本書的讀者中,有很多人沒接受過正規的電腦科學教育。如果你接受過正規的電腦科學教育,那麼,你已經知道了學習資料結構和演算法為何如此重要。如果你沒有一個電腦科學的學位或者沒有正規學習過電腦科學,那麼請耐心讀完本節。

電腦科學家Nicklaus Wirth寫過一本書,書名叫:演算法 + 資料結構 = 程式 (Prentice-Hall)。這個書名就概括了計算機程式設計的精要。除過那些兒戲式的程式,比如“Hello world!”,任何一個有些規模的程式都需要某種形式的資料結構來儲存程式中用到的資料,還需要一個或多個演算法將資料從輸入轉換為輸出。

對於那些沒有在學校學習過電腦科學的程式設計師來說,唯一熟悉的資料結構就是陣列。在處理一些問題時,陣列無疑是很好的,但對於很多複雜的問題,陣列就顯得太過簡陋了。大多數有經驗的程式設計師都願意承認這樣一個事實:對於很多程式設計問題,當他們想出一個合適的資料結構,設計和實現解決這些問題的演算法就變得手到擒來。

二叉查詢樹(BST)就是一個這樣的例子。設計二叉查詢樹的目的是為了方便查詢一組資料中的最小值和最大值,由這個資料結構自然引申出一個查詢演算法,該演算法比市面上最好的查詢演算法效率還要高。不熟悉二叉查詢樹(BST)的程式設計師可能會使用一個更簡單的資料結構,效率上就打了個折扣。

學習演算法非常重要,因為解決同樣的問題,往往存在多種演算法,知道哪種演算法效率最高對一個高效的程式設計師非常重要。比如,現在至少有六、七種排序演算法,如果知道快速排序比選擇排序效率更高,那麼就會讓排序過程變得高效。又比如,實現一個線性查詢的演算法很簡單,但是如果知道有時二分查詢可能比線性查詢快兩倍以上,勢必會寫出一個更好的程式。

深入學習資料結構和演算法,不僅是學習哪種資料結構或演算法更高效,還要學習在資料結構和演算法之間做出選擇,哪種資料結構和演算法對你手頭上的問題是最合適的?寫程式,尤其是拿JavaScript寫程式時,經常會面臨這樣的權衡,知道了本書覆蓋到的資料結構和演算法的優缺點,可以在解決任何特定問題時幫助你做出正確的選擇。

閱讀本書需要的工具

本書使用的程式設計環境是基於SpiderMonkey JavaScript引擎提供的JavaScript Shell。第一章提供了下載和安裝該shell的說明。也可以使用其他一些JavaScript Shell,比如Node.js提供的JavaScript Shell,但是你需要自己對書中的程式做一些轉換,以便可以執行在Node.js上。除了JavaScript Shell,再有一個文字編輯器就夠了,你將使用文字編輯器編寫JavaScript程式。

本書的組織結構

  • 第一章對JavaScript語言做了一個簡單介紹,或者說,至少對本書用到的JavaScript特性做了介紹。本章還展示了貫穿全書的程式設計風格。
  • 第二章討論了計算機程式設計中最常見的資料結構:陣列。陣列是JavaScript原生的資料型別。
  • 第三章介紹了我們實現的第一個資料結構:列表。
  • 第四章介紹了棧。棧是一種貫穿電腦科學的資料結構,編譯器和作業系統的實現都用到了棧。
  • 第五章討論了佇列。佇列是對你在銀行或雜貨店裡排隊時的一種抽象。佇列被大量用在一些模擬軟體中,在處理資料之前,必須先把資料按順序排成一隊。
  • 第六章介紹了連結串列。連結串列是在列表的基礎上進行修改,連結串列裡的每個元素都是一個單獨的物件,該物件和它兩邊中的任何一個元素相連。當程式中需要多次插入和刪除元素時,使用連結串列會非常高效。
  • 第七章展示瞭如何實現是使用字典,字典是一種儲存鍵值對的資料結構。
  • 實現字典的一種方法是通過雜湊表,第八章討論瞭如何實現雜湊表和儲存資料的雜湊演算法。
  • 第九章介紹了集合。和資料結構相關的書通常不會介紹集合,但是當某個資料集不允許有重複元素出現時,使用集合是一個很好的選擇。
  • 第十章的重點是二叉樹和二叉查詢樹。前面提到過,二叉查詢樹是一種儲存有序元素的極佳選擇。
  • 第十一章介紹了圖和圖的演算法。圖用來表示諸如計算機網路上的節點、或者地圖上的城市這樣的資料。
  • 第十二章轉向演算法,討論了各種排序演算法,包括簡單的易實現的演算法,但這種演算法在大的資料集上工作起來效率不高;也包括為大資料集量身定做的複雜一點的演算法。
  • 第十三章還是介紹演算法,不過這回是查詢演算法。介紹了線性查詢和二分查詢。
  • 第十四章是本書的最後一章,討論了一些更高階的演算法——動態規劃和貪心演算法。
    這些演算法能解決一些很難的問題,通常的演算法在面對這些問題時要麼執行速度太慢,要麼難於實現。我們會分析幾個經典的用動態規劃和貪心演算法解決的問題。

致謝

寫完一本書後,總有一些人需要感謝。我要感謝我的組稿編輯Simon St. Laurent,他對本書充滿信心並鼓勵我開始寫這本書。Meghan Blanchette女士為了讓我保持進度費盡心思,如果本書未能按期交付,那一定不是她的錯。Brian MacDonald做了很多工作讓本書變得通俗易懂,他編輯校訂了本書的一些章節,文字比我當初寫就的更清晰。我還要感謝技術審稿人,他們閱讀了本書的全部文字和程式碼,並且指出了行文和程式碼不夠清楚的地方。我的同事,同時也是本書的插圖作者Cynthia Fehrenbach,將我簡陋的草圖繪製成精美、清晰的插圖,在本書將要出版的最後時刻,她還願意重新繪製幾幅插圖,對此我要特別感謝。最後,我要感謝在Mozilla工作的所有人,是他們設計瞭如此出色的JavaScript引擎和Shell,他們還為如何使用JavaScript語言和Shell編寫了非常棒的文件。

相關文章