翻译:程序员数据结构基础:选择正确的数据结构

 

本文转载自GameDev.net,仅供学习交流。因为刚刚开始学习翻译,难免有些疏漏,如果有哪些地方翻译的不正确,请不吝告知,万分感谢。

原文链接:http://www.gamedev.net/page/resources/_/technical/general-programming/data-structures-for-pre-college-programmers-choosing-the-right-structure-r2991

 

网络上的许多初学者还是学生。通常初学者通过在网上看教程,从书上复制代码和尝试一些感兴趣的东西来学习。

这篇文章是初级开发者所需要了解的数据结构基础系列文章中的一篇。前一篇文章分析了非线性数据结构。(Non-Linear Structures.)

这篇文章是帮助初学者理解如何选择一个合适的数据结构或者容器类型。

数据结构

          在该系列的前几篇文章中说明了最常用的一些数据结构,这里只是一个概括。

          线性的结构包括:数组,动态数组和链表。他们之所以是线性的,是因为他们总是呆在你放置他们的地方。数组的随机访问 是非常快的,而且在数组末尾添加和删除数据具有适当良好的性能。如果你频繁地在中间添加或删除数据,链表将是一个非常好的选择。

         线性端点数据结构包括:堆和队列等。他们的工作方式与现实世界中的同名操作非常相似。堆,比如一堆木板或者一个数据堆,你可以把东西放在(push)堆的最上面,可以直接用最早面的一块木板或者数据,或者你可以直接拿掉(pop)最上面的一个木板或都数据。队列,像一人排成一个队伍或一个队列数据,以从队尾加入,从队首移除的方式来工作。

          非线性数据结构包括:数据字典,有序集和无序集。这些结构是内部非线性的,也就是说你把相关数据插入的顺序和取出数据的顺序是基本无关的。数据字典的工作方式与真正的字典非常相似,它拥有一个关键值(key:用来索引的)和值(value:数据值)。一个有序集(ordered set)跟排序过的只包含关键值(key)不包含值(value)的数据字典一样。至于无序集则是像一个数据的抓斗袋(类似抽奖的暗箱),但无序集这个名字是有点误导性的,实际是他们也是有序的,只是他们排序的方式对我们的使用来说是没有什么用的。这些非线性的数据结构非常适合快速的查找数据。

一个好的数据结构的影响

         大多数时候,程序员只是需要遍历整个数据集合。通常,当我们需要从头访问每个数据项时,我们不关心数据内部是怎么排序的。这种常见的情况中,数据结构的选择不是很大的问题。

        当有疑问的时候最普遍的选择是动态数组,它可以变成任意的大小,中规中矩,在后期有需要时也可以很容易的转换成其它的数据结构。

       但有时候他也有一些问题。

       在游戏中,一个很常见的问题就是寻路。你需要找出一个从ab的路径。最常见的寻路算法是a星算法。在a星算法中你需要一个数据结构来存储部分路径。这个结构应该是排序过的,这样可以把我们最最想要的路径摆放在容器的最前面方便我们使用。如果该路被检测后发现不是一个完整的路径,该算法则会使他成为一个更大的路径的一部分并加入的相当的容器中。 

         使用动态数组作为a星算法的容器将会是一个糟糕的选择,原因如下:

  1. 从动态数组的开头移除一个数组是我们所能执行最低效的一个操作。
  2. 当加入了一个新的路径,我们对动态数组进行重新排序是非常低效的。

 

          如果记得之前所说的,还有是这种类型的访问的最优化的数据结构。我们可以移除最前面的数据,把数据从最后面插入,并自动重排索引出最佳的路径。优先队列是a星算法容器类型的一个好的选择。它通常都内置在语言内部,并通过完善的测试。

根据使用的模式来写选择

          使用什么样的数据结构,通常依据你所使用的设计模式。

动态数组 -- 默认的选择

          当有疑问的时候,使用动态数组。在c++叫做vector,在java中叫做ArrayList,c#中叫做List

          动态数组通常可以符合使用要求。它大多数操作都有好的性能 ,剩余的操作性能也不差。如果你发现你需要其它的数据结构,动态数组也是最容易进行修改的。

-- 只有一端

           如果你只在单独的一端添加或删除。使用堆,在c++中是stack,在javac#中都叫Statck

           有许多算法依赖堆来实现。我的第一个反应就是双堆计算器(two-stack calculator)。数学问题像汉诺塔也可以通过堆来解决。当然,在游戏编程中,你可能用不到他们。

            游戏工具经验解析数据。解析器在很大程度上依赖堆数据结构来保证配对项匹配正确。

             如果你正在使用各种各样的ai类型。你可以发现堆数据结构对于自动机家族中的自动下推器是难以估计的实用。

队列 -- 先进先出

          如果你需要从两端进行增删数据,那你你可以使用队列或者双端队列。在c++中叫做queue(队列)或者deque(双端队列).java中你可以使用Queue或者Deque接口,都是基于LinkList实现的。在c#中只有一个Queue类型,没有内置双端队列(deque)。

          如果你需要保证某些重要的东西第一时间被处理,但除非所有的事情都有序的发生,并且按优先级顺序完成。这时你可以使用优先级队列来处理,在c++中称为priority_queue.java中称为PriorityQueue.C#中你需要自己来实现这个优先级队列。

非线性结构 -- 快速索引

         如果你需要创建一个稳定的数据结构,并频繁的进行随机查找,那么你需要使用非线性数据结构。

         非线性数据结构有的保存一对数据,有的保存独立的数据。有的是对用户友好的排序,有的是对计算机友好的排序。如果要列出他们之间的所有组合,又将是一篇文章。实际上,那些在之前的文章中已经详细的描述过了。 对于这些非线性结构哪些满足特定的需求,可以查看之前的关于非线性数据结构的文章

链表 -- 频繁有序的修改

         如果你需要频繁的在容器中间进行操作数据(增删),而且你只需要顺序的遍历列表。你可以使用链表,在c++中称为list, javac#中称为LinkedList

        当数据需要频繁的增删,并且在增删后必须保持有序状态时,链表是一个非常好的容器选择。

结论

         选择正确的数据结构可以让算法的性能是非常大的改善。

        理解主要的数据结构,包含他们的优缺点可以帮助你选择你所需要的数据结构。

        我建议你们深入的研究学习这些主要的数据结构。深入学习这些数据结构的计算机科学学位课程通常会持续数星期内。

        希望你已经了解了主要的数据结构,可以在没有进行数周深入的学习这些数据结构时可以选择一个好的数据结构。

         这系列的文章已经结束了,感谢阅读。

本文转载自GameDev.net,仅供学习交流。因为刚刚开始学习翻译,难免有些疏漏,如果有哪些地方翻译的不正确,请不吝告知,万分感谢。

原文链接:http://www.gamedev.net/page/resources/_/technical/general-programming/data-structures-for-pre-college-programmers-choosing-the-right-structure-r2991

 

转载于:https://www.cnblogs.com/wtu-sos/p/5118860.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于Xcode隐藏打印的logs的方法

https://www.cnblogs.com/jukaiit/p/5881062.html 第一步: 第二步: 第三步: 添加参数: Name :OS_ACTIVITY_MODE Value : disable

指针函数与函数指针的区别

首先它们之间的定义:1、指针函数是指带指针的函数,即本质是一个函数,函数返回类型是某一类型的指针。 类型标识符 *函数名(参数表)int *f(x,y);首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用…

数组字典

#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) {autoreleasepool { //把字典放到数组中NSDictionary *dic1{"name":"小明","class":"IOS8","age":"22"};NSDictionary *dic2{&…

C++走向远洋——63(项目二2、两个成员的类模板)

*/ * Copyright (c) 2016&#xff0c;烟台大学计算机与控制工程学院 * All rights reserved. * 文件名&#xff1a;text.cpp * 作者&#xff1a;常轩 * 微信公众号&#xff1a;Worldhello * 完成日期&#xff1a;2016年6月4日 * 版本号&#xff1a;V1.0 * 问题描述&…

iOS 抓包工具 charles工具

在Charles官网下载最新的 安装包 在电脑上安装完成之后&#xff0c;以 注册码 Registered Name: https://zhile.io License Key: 48891cf209c6d32bf4 进行注册即可完成 在手机上面设置代理&#xff1a;输入电脑的网络IP以及端口号 以下为查找的步骤&#xff1a; 在手机上手…

指针数组与数组指针详解

指针数组与数组指针详解 1.什么是指针数组和数组指针&#xff1f; 指针数组&#xff1a;指针数组可以说成是”指针的数组”&#xff0c;首先这个变量是一个数组&#xff0c;其次&#xff0c;”指针”修饰这个数组&#xff0c;意思是说这个数组的所有元素都是指针类型&#xff0…

写一个Android输入法01——最简步骤

本文演示用Android Studio写一个最简单的输入法。界面和交互都很简陋&#xff0c;只为剔肉留骨&#xff0c;彰显写一个Android输入法的要点。 1、打开Android Studio创建项目&#xff0c;该项目和普通APP的不同之处在于它不需要添加任何Activity&#xff1a;我给该输入法命名为…

句柄与指针的区别

句柄实际上是一种指向某种资源的指针&#xff0c;但与指针又有所不同&#xff1a;指针对应着一个数据在内存中的地址&#xff0c;得到了指针就可以自由地修改该数据。 Windows并不希望一般程序修改其内部数据结构&#xff0c;因为这样太不安全。所以Windows给每个使用GlobalAll…

iOS 11 适配

http://blog.csdn.net/st646889325/article/details/79066361 这一个不错的文章

谈谈自己对于Auth2.0的见解

Auth的原理网上有很多&#xff0c;我这里就不在赘述了。 这里有张时序图我个人觉得是比较合理而且直观的&#xff0c;&#xff08;感谢这篇博文&#xff1a;http://justcoding.iteye.com/blog/1950270&#xff09; 参照这个流程&#xff0c;模拟了下部分代码&#xff0c;当然是…

某个时间点 几天后

1、某个时间点 3天后 NSDate *maxDate [NSDate dateWithTimeInterval:3 * 24 * 60 * 60 sinceDate:date];//3天后 2、现在 3天后 NSDate *minDate [[NSDate date] initWithTimeIntervalSinceNow:3 * 24 * 60 * 60];

iPad开发--QQ空间,处理横竖屏布局,实现子控件中的代理

一.主界面横竖屏效果图 二.主界面加载, 初始化Dock(红色框的控件),判断程序启动时的屏幕方向.调用自己- (void)transitionToLandScape:(BOOL)isLandScape;方法,通知子控件屏幕方向改变,将此事件一直传递下去程序运行过程中屏幕方向改变会调用- (void)viewWillTransitionToSize:…

C++ Vector 汇总

C vector erase函数最近使用了顺序容器的删除元素操作&#xff0c;特此记录下该函数的注意事项。 在Cprimer中对c.erase(p) 这样解释的&#xff1a;c.erase(p) 删除迭代器p所指向的元素&#xff0c;返回一个指向被删元素之后元素的迭代器&#xff0c;若p指向尾元素&#xff…

vNext之旅(2):net451、dotnet5.4、dnx451、dnxcore50都是什么鬼

继上次”vNext之旅&#xff08;1&#xff09;&#xff1a;从概念和基础开始”之后再次学习vNext重新遇到了弄不懂的事情&#xff0c;花了一些时间学习&#xff0c;今天来分享一下&#xff0c;为后人节省些时间。起因 在用vNext造轮子——框架的时候引入“Microsoft.Dnx.Runtime…

C++中模板使用详解

转自&#xff1a;http://www.360doc.com/content/09/0403/17/799_3011262.shtml 1. 模板的概念。 我们已经学过重载(Overloading)&#xff0c;对重载函数而言,C的检查机制能通过函数参数的不同及所属类的不同。正确的调用重载函数。例如&#xff0c;为求两个数的最大值&#xf…

腾讯2016春招安全岗笔试题解析

腾讯2016春招安全岗笔试题解析 昨天&#xff08;4月2日&#xff09;晚上7:00到9:00做了腾讯春招安全岗的笔试题。下面解析一下&#xff1a; 题目解析 1 在生成随机数前用当前时间设置随机数种子应该是安全的。如果程序用固定的数产生随机数&#xff0c;其结果也是固定的。如果用…

网络请求数据解析时,判断数据是否为空

//判断是否为空 (BOOL)IsStringEmptyOrNull:(NSString *)str { if (!str) { // null object return true; }else if (str nil){ return true; }else { if ([str isKindOfClass:[NSNull class]]) { return true; …

VS项目属性的一些配置项的总结(持续增加。。。)

首先&#xff0c;解决方案和项目文件夹包含关系(c项目)&#xff1a; VS解决方案和各个项目文件夹以及解决方案和各个项目对应的配置文件包含关系&#xff1a;假设新建一个项目ssyy&#xff0c;解决方案起名fangan&#xff0c;注意解决方案包括项目&#xff0c;此时生成的最外层…

shell编程中date用法(转)

原文地址:http://blog.sina.com.cn/s/blog_61c006ea0100mgxe.html 1、date --help %% 输出%符号 a literal % %a 当前域的星期缩写 locale’s abbreviated weekday name (Sun..Sat) %A 当前域的星期全写 locale’s full weekday name, variable length (Sunday..Saturday) %b 当…

linux下搭建FTP服务器

LINUX FTP简单配置 FTP配置1、#vi /etc/vsftp/vsftpd.conf #主要配置几个关键的就可以 anonymous_enableNO #拒绝匿名访问 chroot_local_userYES #锁定用户目录&#xff0c…