翻译:程序员数据结构基础:选择正确的数据结构
?
本文轉(zhuǎn)載自GameDev.net,僅供學(xué)習(xí)交流。因?yàn)閯倓傞_始學(xué)習(xí)翻譯,難免有些疏漏,如果有哪些地方翻譯的不正確,請(qǐng)不吝告知,萬(wàn)分感謝。
原文鏈接:http://www.gamedev.net/page/resources/_/technical/general-programming/data-structures-for-pre-college-programmers-choosing-the-right-structure-r2991
?
網(wǎng)絡(luò)上的許多初學(xué)者還是學(xué)生。通常初學(xué)者通過在網(wǎng)上看教程,從書上復(fù)制代碼和嘗試一些感興趣的東西來(lái)學(xué)習(xí)。
這篇文章是初級(jí)開發(fā)者所需要了解的數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)系列文章中的一篇。前一篇文章分析了非線性數(shù)據(jù)結(jié)構(gòu)。(Non-Linear Structures.)
這篇文章是幫助初學(xué)者理解如何選擇一個(gè)合適的數(shù)據(jù)結(jié)構(gòu)或者容器類型。
數(shù)據(jù)結(jié)構(gòu)
????????? 在該系列的前幾篇文章中說(shuō)明了最常用的一些數(shù)據(jù)結(jié)構(gòu),這里只是一個(gè)概括。
????????? 線性的結(jié)構(gòu)包括:數(shù)組,動(dòng)態(tài)數(shù)組和鏈表。他們之所以是線性的,是因?yàn)樗麄兛偸谴粼谀惴胖盟麄兊牡胤健?shù)組的隨機(jī)訪問 是非常快的,而且在數(shù)組末尾添加和刪除數(shù)據(jù)具有適當(dāng)良好的性能。如果你頻繁地在中間添加或刪除數(shù)據(jù),鏈表將是一個(gè)非常好的選擇。
???????? 線性端點(diǎn)數(shù)據(jù)結(jié)構(gòu)包括:堆和隊(duì)列等。他們的工作方式與現(xiàn)實(shí)世界中的同名操作非常相似。堆,比如一堆木板或者一個(gè)數(shù)據(jù)堆,你可以把東西放在(push)堆的最上面,可以直接用最早面的一塊木板或者數(shù)據(jù),或者你可以直接拿掉(pop)最上面的一個(gè)木板或都數(shù)據(jù)。隊(duì)列,像一人排成一個(gè)隊(duì)伍或一個(gè)隊(duì)列數(shù)據(jù),以從隊(duì)尾加入,從隊(duì)首移除的方式來(lái)工作。
????????? 非線性數(shù)據(jù)結(jié)構(gòu)包括:數(shù)據(jù)字典,有序集和無(wú)序集。這些結(jié)構(gòu)是內(nèi)部非線性的,也就是說(shuō)你把相關(guān)數(shù)據(jù)插入的順序和取出數(shù)據(jù)的順序是基本無(wú)關(guān)的。數(shù)據(jù)字典的工作方式與真正的字典非常相似,它擁有一個(gè)關(guān)鍵值(key:用來(lái)索引的)和值(value:數(shù)據(jù)值)。一個(gè)有序集(ordered set)跟排序過的只包含關(guān)鍵值(key)不包含值(value)的數(shù)據(jù)字典一樣。至于無(wú)序集則是像一個(gè)數(shù)據(jù)的抓斗袋(類似抽獎(jiǎng)的暗箱),但無(wú)序集這個(gè)名字是有點(diǎn)誤導(dǎo)性的,實(shí)際是他們也是有序的,只是他們排序的方式對(duì)我們的使用來(lái)說(shuō)是沒有什么用的。這些非線性的數(shù)據(jù)結(jié)構(gòu)非常適合快速的查找數(shù)據(jù)。
一個(gè)好的數(shù)據(jù)結(jié)構(gòu)的影響
? ? ? ? ?大多數(shù)時(shí)候,程序員只是需要遍歷整個(gè)數(shù)據(jù)集合。通常,當(dāng)我們需要從頭訪問每個(gè)數(shù)據(jù)項(xiàng)時(shí),我們不關(guān)心數(shù)據(jù)內(nèi)部是怎么排序的。這種常見的情況中,數(shù)據(jù)結(jié)構(gòu)的選擇不是很大的問題。
??????? 當(dāng)有疑問的時(shí)候最普遍的選擇是動(dòng)態(tài)數(shù)組,它可以變成任意的大小,中規(guī)中矩,在后期有需要時(shí)也可以很容易的轉(zhuǎn)換成其它的數(shù)據(jù)結(jié)構(gòu)。
?????? 但有時(shí)候他也有一些問題。
?????? 在游戲中,一個(gè)很常見的問題就是尋路。你需要找出一個(gè)從a到b的路徑。最常見的尋路算法是a星算法。在a星算法中你需要一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)部分路徑。這個(gè)結(jié)構(gòu)應(yīng)該是排序過的,這樣可以把我們最最想要的路徑擺放在容器的最前面方便我們使用。如果該路被檢測(cè)后發(fā)現(xiàn)不是一個(gè)完整的路徑,該算法則會(huì)使他成為一個(gè)更大的路徑的一部分并加入的相當(dāng)?shù)娜萜髦小?span lang="en-us">?
???????? 使用動(dòng)態(tài)數(shù)組作為a星算法的容器將會(huì)是一個(gè)糟糕的選擇,原因如下:
?
????????? 如果記得之前所說(shuō)的,還有是這種類型的訪問的最優(yōu)化的數(shù)據(jù)結(jié)構(gòu)。我們可以移除最前面的數(shù)據(jù),把數(shù)據(jù)從最后面插入,并自動(dòng)重排索引出最佳的路徑。優(yōu)先隊(duì)列是a星算法容器類型的一個(gè)好的選擇。它通常都內(nèi)置在語(yǔ)言內(nèi)部,并通過完善的測(cè)試。
根據(jù)使用的模式來(lái)寫選擇
????????? 使用什么樣的數(shù)據(jù)結(jié)構(gòu),通常依據(jù)你所使用的設(shè)計(jì)模式。
動(dòng)態(tài)數(shù)組 -- 默認(rèn)的選擇
????????? 當(dāng)有疑問的時(shí)候,使用動(dòng)態(tài)數(shù)組。在c++叫做vector,在java中叫做ArrayList,在c#中叫做List。
????????? 動(dòng)態(tài)數(shù)組通常可以符合使用要求。它大多數(shù)操作都有好的性能 ,剩余的操作性能也不差。如果你發(fā)現(xiàn)你需要其它的數(shù)據(jù)結(jié)構(gòu),動(dòng)態(tài)數(shù)組也是最容易進(jìn)行修改的。
堆 -- 只有一端
?????????? 如果你只在單獨(dú)的一端添加或刪除。使用堆,在c++中是stack,在java和c#中都叫Statck。
?????????? 有許多算法依賴堆來(lái)實(shí)現(xiàn)。我的第一個(gè)反應(yīng)就是雙堆計(jì)算器(two-stack calculator)。數(shù)學(xué)問題像漢諾塔也可以通過堆來(lái)解決。當(dāng)然,在游戲編程中,你可能用不到他們。
??????????? 游戲工具經(jīng)驗(yàn)解析數(shù)據(jù)。解析器在很大程度上依賴堆數(shù)據(jù)結(jié)構(gòu)來(lái)保證配對(duì)項(xiàng)匹配正確。
???????????? 如果你正在使用各種各樣的ai類型。你可以發(fā)現(xiàn)堆數(shù)據(jù)結(jié)構(gòu)對(duì)于自動(dòng)機(jī)家族中的自動(dòng)下推器是難以估計(jì)的實(shí)用。
隊(duì)列 -- 先進(jìn)先出
????????? 如果你需要從兩端進(jìn)行增刪數(shù)據(jù),那你你可以使用隊(duì)列或者雙端隊(duì)列。在c++中叫做queue(隊(duì)列)或者deque(雙端隊(duì)列).在java中你可以使用Queue或者Deque接口,都是基于LinkList實(shí)現(xiàn)的。在c#中只有一個(gè)Queue類型,沒有內(nèi)置雙端隊(duì)列(deque)。
????????? 如果你需要保證某些重要的東西第一時(shí)間被處理,但除非所有的事情都有序的發(fā)生,并且按優(yōu)先級(jí)順序完成。這時(shí)你可以使用優(yōu)先級(jí)隊(duì)列來(lái)處理,在c++中稱為priority_queue.在java中稱為PriorityQueue.C#中你需要自己來(lái)實(shí)現(xiàn)這個(gè)優(yōu)先級(jí)隊(duì)列。
非線性結(jié)構(gòu) -- 快速索引
???????? 如果你需要?jiǎng)?chuàng)建一個(gè)穩(wěn)定的數(shù)據(jù)結(jié)構(gòu),并頻繁的進(jìn)行隨機(jī)查找,那么你需要使用非線性數(shù)據(jù)結(jié)構(gòu)。
???????? 非線性數(shù)據(jù)結(jié)構(gòu)有的保存一對(duì)數(shù)據(jù),有的保存獨(dú)立的數(shù)據(jù)。有的是對(duì)用戶友好的排序,有的是對(duì)計(jì)算機(jī)友好的排序。如果要列出他們之間的所有組合,又將是一篇文章。實(shí)際上,那些在之前的文章中已經(jīng)詳細(xì)的描述過了。 對(duì)于這些非線性結(jié)構(gòu)哪些滿足特定的需求,可以查看之前的關(guān)于非線性數(shù)據(jù)結(jié)構(gòu)的文章。
鏈表 -- 頻繁有序的修改
???????? 如果你需要頻繁的在容器中間進(jìn)行操作數(shù)據(jù)(增刪),而且你只需要順序的遍歷列表。你可以使用鏈表,在c++中稱為list, 在java和c#中稱為LinkedList。
??????? 當(dāng)數(shù)據(jù)需要頻繁的增刪,并且在增刪后必須保持有序狀態(tài)時(shí),鏈表是一個(gè)非常好的容器選擇。
結(jié)論
???????? 選擇正確的數(shù)據(jù)結(jié)構(gòu)可以讓算法的性能是非常大的改善。
??????? 理解主要的數(shù)據(jù)結(jié)構(gòu),包含他們的優(yōu)缺點(diǎn)可以幫助你選擇你所需要的數(shù)據(jù)結(jié)構(gòu)。
??????? 我建議你們深入的研究學(xué)習(xí)這些主要的數(shù)據(jù)結(jié)構(gòu)。深入學(xué)習(xí)這些數(shù)據(jù)結(jié)構(gòu)的計(jì)算機(jī)科學(xué)學(xué)位課程通常會(huì)持續(xù)數(shù)星期內(nèi)。
??????? 希望你已經(jīng)了解了主要的數(shù)據(jù)結(jié)構(gòu),可以在沒有進(jìn)行數(shù)周深入的學(xué)習(xí)這些數(shù)據(jù)結(jié)構(gòu)時(shí)可以選擇一個(gè)好的數(shù)據(jù)結(jié)構(gòu)。
???????? 這系列的文章已經(jīng)結(jié)束了,感謝閱讀。
本文轉(zhuǎn)載自GameDev.net,僅供學(xué)習(xí)交流。因?yàn)閯倓傞_始學(xué)習(xí)翻譯,難免有些疏漏,如果有哪些地方翻譯的不正確,請(qǐng)不吝告知,萬(wàn)分感謝。
原文鏈接:http://www.gamedev.net/page/resources/_/technical/general-programming/data-structures-for-pre-college-programmers-choosing-the-right-structure-r2991
?
轉(zhuǎn)載于:https://www.cnblogs.com/wtu-sos/p/5118860.html
總結(jié)
以上是生活随笔為你收集整理的翻译:程序员数据结构基础:选择正确的数据结构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端,标签
- 下一篇: 通过带数据盘的自定义镜像来创建使用应用程