01
招聘趣事
如果你關注計算機專業招聘試題,會發現越是大型公司,問的問題越基礎,有的甚至問你什麼是棧和隊列,反而一些小公司會關心你做過什麼系統。從關注點的不同可以看出,大公司更注重基礎紮實和發展潛力,而小公司希望你立刻能夠為其幹活。可以這樣比喻:小公司喜歡細而長的竹子,大公司更喜歡碗口粗的竹筍。
我曾經推薦一個學生到某知名公司,沒多久,學生向我說了應聘的事情:“我介紹我開發了企業管理系統、線上商城系統等,沒想到他問我使用了什麼資料結構和算法,我懂很多技術,那麼多功能我都實作了,他不問,卻問我使用了什麼資料結構和算法,你說搞笑不?資料結構和算法我早就忘了,我會開發軟體還不行嗎?”人力資源總監也回報過來意見:“很搞笑,這個學生做了不少系統,卻說根本沒用到資料結構和算法。”
既然雙方都覺得這是一件搞笑的事情,那麼我們就攤開來看,資料結構到底是什麼。
02
撥雲見日,看清資料結構
當我們遇到一個實際問題時,首先需要解決兩件事:
(1)如何将資料存儲在計算機中;
(2)用什麼方法和政策解決問題。
前者是資料結構,後者是算法。隻有資料結構沒有算法,相當于隻把資料存儲到計算機中,而沒有有效的方法去處理,就像一幢隻有架構的爛尾樓;若隻有算法,沒有資料結構,就像沙漠裡的海市蜃樓,隻不過是空中樓閣罷了。
資料是一切能輸入計算機中的資訊的總和,結構是指資料之間的關系。資料結構就是将資料及其之間的關系有效地存儲在計算機中并進行基本操作。算法是對特定問題求解步驟的一種描述,通俗講就是解決問題的方法和政策。
在遇到一個實際問題時,要充分利用自己所學的資料結構,将資料及其之間的關系有效地存儲在計算機中,然後選擇合适的算法政策,并用程式高效地實作。這就是Niklaus Wirth教授所說的:“資料結構+算法=程式”。
03
為什麼要學習資料結構
高校的計算機專業為大學生都開設了資料結構課程,它是計算機學科知識結構的核心和技術體系的基石,在研究所學生考試中也是必考科目。随着科學技術的飛速發展,資料結構的基礎性地位不僅沒有動搖,反而因近年來算法工程師的高薪形勢,而得到了業内空前的重視。很多人認為基本的資料結構及操作已經在進階語言(如C++、Java語言)中封裝,棧、隊列、排序、優先隊列等都可以直接調用庫函數,學會怎麼調用就好了,為什麼要重複“造輪子”?那麼到底有沒有必要好好學習資料結構呢?
先看學習資料結構有什麼用處。
(1)學習有效存儲資料的方法。很多學生在學習資料結構時,問我要不要把單連結清單插入、删除背下來?要不合上書就不會寫了。我非常詫異,為什麼要背?理工科技術知識很少需要記憶的,是用的,用的!學習知識不能隻靠死記硬背,更重要的是學習處理問題的方法。如何有效地存儲資料,不同的資料結構産生什麼樣的算法複雜性,有沒有更好的存儲方法提高算法的效率?
(2)處理具有複雜關系的資料。現實中很多具有複雜關系的資料無法通過簡單的庫函數調用實作。如同現在很多晶片高度內建,完全不需要知道晶片内部如何,直接使用就行了。但是,如果在現實中遇到一個複雜
QQ号出售問題,現有的晶片根本無法解決,或者一個晶片隻能完成其中一個功能,而我們需要的是完成該複雜問題的一個內建晶片,這時就需要運用所學的資料結構知識來高效處理具有複雜關系的資料。
(3)提高算法效率。很多問題的基礎資料結構運作效率較低,需要借助進階資料結構或通過改進資料結構來提高算法效率。
通過學習資料結構,更加準确和深刻地了解不同資料結構之間的共性和聯系,學會選擇和改進資料結構,高效地設計并實作各種算法,這才是資料結構的精髓。
04
資料結構為什麼那麼難
網絡上太多的同學吐槽被“虐”,如“滔滔江水連綿不絕”,資料結構太難了!真的很難嗎?其實資料結構隻是講了3部分内容:線性結構、樹和圖。到底難在哪裡呢?我通過調查,了解到資料結構難學大概有以下4個原因。
(1)無法接受它的描述方式。資料結構的描述大多是抽象的形式,我們習慣了使用自然語言表達,難以接受資料結構的抽象表達。運作時怎麼經常提示錯誤。它的意思就是“元素類型”,隻是這樣來描述,你需要什麼類型就寫什麼類型,例如int。這樣的表達方式會讓不少人感到崩潰。
(2)不知道它有什麼用處。盡管很多人學習資料結構,但目的各不相同。有的人是應付考試,有的人是參加算法競賽需要,而很多人不太清楚學習資料結構有什麼用處,迷迷糊糊看書、做題、考試。
(3)體會不到其中的妙處。由于各種因素影響,很多學生沒有體會到資料結構處理資料的妙處,經常為學不會而焦頭爛額,學習重在體會其中的樂趣,有樂趣才有興趣,興趣是最好的驅動力。
(4)語言基礎不好。我一直強調先看圖解,理清思路,再上機。可還是有很多同學已經了解了思路後,因為缺少main函數,輸入/輸出格式不對,缺少括号等各種語言問題卡殼,而這一切都被戴上了“資料結構太難了”的大帽子。
05
資料結構學習秘籍
在講學習秘籍之前,我們首先了解一下資料結構學習的3種境界。
(1)會資料結構的基本操作。學會各種資料結構的基本操作,即取值、查找、插入、删除等,是最基礎的要求。先看圖解,了解各種資料結構的定義,操作方法,然後看代碼,嘗試自己動手上機運作,逐漸掌握基本操作。在初學時,要想了解資料結構,一定要學會畫圖。通過畫圖形象表達,能更好地體會其中的資料結構關系。是以,初學階段學習利器是:畫圖、了解、畫圖。
(2)會利用資料結構解決實際問題。在掌握了書中的基本操作之後,就可以嘗試利用資料結構解決一些實際問題了。先學經典應用問題的解決方法,體會資料結構的使用方法,再做題,獨立設計資料結構解決問題。要想熟練應用就必須做大量的題,在做題的過程中體會其中的方法。最好進行專項練習,比如線性表問題、二叉樹問題、圖問題。這一階段的學習利器是:做題、反思、做題。
(3)熟練使用和改進資料結構,優化算法。這是最高境界了,也是學習資料結構的精髓所在,單獨學習資料結構是無法達到這種境界的。資料結構與算法相輔相成,需要在學習算法的過程中慢慢修煉。在學習算法的同時,逐漸熟練應用、改進資料結構,慢慢體會不同資料結構和算法政策的算法複雜性,最終學會利用資料結構改進和優化算法。這一階段已經在資料結構之上,可以通過在ACM測試系統上刷各種算法題,體會資料結構在算法設計中的應用。這一階段的學習利器是:刷題、總結、刷題。