我应该“识别”并按名称知道哪些算法/数据结构?[关闭]


69

我想将自己视为一个经验丰富的程序员。我已经编程超过5年了。我的弱点是术语。我是自学成才的,因此尽管我知道如何编程,但我不了解计算机科学的一些更正式的方面。那么,按名称我可以识别和知道的实用算法/数据结构是什么?

请注意,我并不是在要求有关实现算法的书建议。我不在乎实现它们,我只是想知道什么时候算法/数据结构可以很好地解决问题。我要更多的是我应该“识别”的算法/数据结构的列表。例如,我知道解决此类问题的方法:

您管理一组标记为0-999的储物柜。人们来找您租用储物柜,然后回来找回储物柜钥匙。您将如何构建一个软件来管理哪些储物柜是免费的,哪些储物柜正在使用?

解决方案是队列或堆栈。

我正在寻找的是诸如“在什么情况下应使用B树-在此处应使用哪种搜索算法”之类的信息。也许还可以快速介绍一下如何使用更复杂(但常用的)数据结构/算法起作用。

我尝试查看Wikipedia的数据结构算法列表,但我认为这有点过头了。因此,我正在寻找我应该认识的基本要素?


10
投票关闭为“非建设性的”。任何答案都将完全是主观的-对于“应该”知道什么没有达成共识。
奥德

2
储物柜问题的哪一部分需要输入/输出排序?[提示!]
Telastyn 2012年

5
@Oded绝对有一个清单,我认为大多数人都会同意一个精通的程序员应该知道哪些数据结构和算法。
大卫·考登

6
@奥德没有共识?关于计算机科学算法和数据结构入门课程的课程提纲如何?标准化程度很高,同行评审。一个好的起点。
MarkJ 2012年

3
替代解决方案;假设您按天收费,并已达到最高收费。放储物柜并在上面写上儒略日编号时,请在钥匙上贴上纸标签。返回键后,查看标签以计算应付租金。标签丢失或污损会招致最大费用。未使用的钥匙存储在袋子中(因为放储物柜时无需从自由钥匙中选择任何特定的钥匙)。数据结构总大小:零位。该算法的所有部分均为O(1)。
James Youngman

Answers:


78

客观回应:

虽然我最初对这个问题的回答是基于我作为一名即将毕业的CS学生的经验,以及我对我想与CS领域一起工作的人的类型的预期观点。实际上有一个客观的答案(关于ACM SIGCSE和IEEE计算协会的主观意见)。ACMIEEE机构每10年合作发表一份联合出版物,其中详细介绍了基于计算机行业状况的专业知识为本科计算机科学课程提供建议。有关更多信息,请访问cs2013.org。该委员会发布了一份最终报告,列出了他们的课程建议

话虽如此,我仍然认为我的名单还不错。

以下是原始答案。


我应该知道些什么?

最低要求

我认为熟练的程序员至少应具有计算机科学的本科知识。当然,由于CS座落于坚如磐石的社区中,而且大多数专业职位的工作范围缩小,因此仅使用一小部分计算机科学就可以在许多工作中发挥作用。同样,许多人将在大学学习后进一步专注于专业。但是,我也不认为没有基础的CS知识也不是借口。

为了回答标题问题,以下是本科生CS学生(熟练的程序员的基础)毕业后应了解的知识:

数据结构

  • 机器数据表示
    • 一个,两个的补码及相关算法
    • 单词,指针,浮点数
    • 位访问,移位和操作
  • 链表
  • 哈希表(地图或字典)
  • 数组
  • 树木
  • 堆栈
  • Queue列
  • 图表
  • 资料库

演算法

  • 排序:
    • 冒泡排序(知道为什么不好)
    • 插入排序
    • 合并排序
    • 快速排序
    • 基数样式排序,计数排序和存储桶排序
    • 堆排序
    • Bogo和Quantum Sort(=
  • 搜索:
    • 线性搜寻
    • 二进制搜索
    • 深度优先搜索
    • 广度优先搜索
  • 字符串操作
  • 迭代
  • 树遍历
  • 列表遍历
  • 散列函数
  • 哈希表,树,列表,堆栈,队列,数组以及集合或集合的具体实现
  • 调度算法
  • 文件系统遍历和操作(在inode或等效级别上)。

设计模式

  • 模块化
  • 建造者
  • 辛格尔顿
  • 适配器
  • 装饰器
  • 飞行重量
  • 观察者
  • 迭代器
  • 状态[机器]
  • 模型视图控制器
  • 线程和并行编程模式

范式

  • 势在必行
  • 面向对象
  • 功能性
  • 陈述式
  • 静态和动态编程
  • 数据标记

复杂性理论

  • 复杂性空间
  • 可计算性
  • 常规,上下文无关和通用图灵机完整语言
  • 常用表达
  • 计数与基本组合

超越

如果您熟悉上述内容,然后再进入问题的后面,您应该可以轻松确定给定方案的适当模式,算法和数据结构。但是,您应该认识到通常没有最佳解决方案。有时,您可能需要从两个弊端中取较小者,甚至只是在两个同样可行的解决方案之间进行选择。因此,您需要具备一些常识才能抵御同行的选择。

以下是有关算法和数据结构的一些技巧:

  • 二进制搜索只能(并且应该)用于排序的数据。
  • 基数样式排序很棒,但是仅当您要对事物进行有限分类时才可以。
  • 树对哈希表几乎无所不能。哈希表的功能可以外推并用于以效率为代价解决许多问题。
  • 数组可用于支持大多数更高级别的数据结构。有时,“数据结构”不过是一些用于访问数组中位置的精巧数学。
  • 语言的选择可以是将头发拉出问题或解决问题之间的区别。
  • ASCII表和128个元素的数组构成一个隐式哈希表(=
  • 正则表达式可以解决很多问题,但是不能用于解析HTML
  • 有时,数据结构与算法一样重要。

上面的某些内容似乎没有任何道理,而某些内容似乎含糊不清。如果您想让我进一步介绍,我可以。但是,我的希望是遇到一个更具体的问题,例如“设计一个可计算字符串中每个字符出现次数的函数”,您会看到有关ASCII表和构成整洁的隐式哈希的128个元素数组的提示表的答案。

基于这些想法,我将为您的问题中提出的储物柜问题提出一个答案。


回答问题中提出的问题。

这可能不是您问题的最佳答案,但我认为这是一个有趣的问题,不需要太复杂。这肯定会克服使用队列或堆栈的时间复杂性,而队列或堆栈需要线性时间来确定储物柜是否空闲。

您有0-999个储物柜。现在,由于您有固定数量的储物柜,因此可以轻松构想出散列函数,且不会在0-999范围内发生冲突。这个函数只是h(x)= x mod1000。现在,[概念上]构造一个具有整数键和1000元素char数组的内容作为您的值的哈希表。如果客户想保留储物柜78以供使用,只需将78放入哈希函数中(返回78),然后将该数字添加到数组的基本指针中-将真实值存储在偏移值所指向的位置。同样,如果需要检查是否正在使用78,只需读取存储在该位置的值并检查是否为true。

与二进制树支持的优先级队列的情况相比,此解决方案以固定的时间运行以进行查找和存储,而不是log(n)时间存储和查找。该描述是特意冗长的,因此您可以看到将更高级的概念简化为一种有效的算法。

现在,您可能会问,如果我需要知道所有可用的储物柜,优先级队列会更好吗?如果优先级队列中有k个可用的储物柜,则对所有这些储物柜进行迭代将需要k个步骤。此外,根据优先级队列的实现,您可能需要重建所有优先级队列,这需要k * log(k):(k <1000)步骤。在数组解决方案中,您只需要迭代1000个元素数组并检查哪些数组是打开的。您还可以向实现中添加可用列表或已使用列表,以仅签入k次。


1
好答案!我还要补充一点,您确实应该对使用所用语言的预定义函数/数据结构充满信心,例如C ++中的算法和stl数据结构,或Java Java API。
marktani 2012年

1
优秀的!尤其是“正则表达式可以解决很多问题,但不能用来解析HTML。”
FrustratedWithFormsDesigner 2012年

2
答案是好的,直到出现“问题”。完全没有理由使用优先级队列或哈希表。一个简单的堆栈就足够了。如果需要,可以添加迭代以获取免费储物柜的完整列表。
Matthieu M.

1
我们是否应该添加关系数据库+ SQL,B +树知识,编译器理论,知识硬件组织,操作系统理论知识,TCP / IP网络知识?
dan_l 2012年

1
我对设计模式表示怀疑。许多语言在某些类型的语言中很有用,而在其他语言中则无用和/或不必要。您可能还想在算法下添加启发式方法,以及trie和skip-list数据结构。传统算法/数据结构在同步访问上达到了极限,但是可以被使用多个线程和并发性的其他非传统方法所击败。启发式方法可以极大地减少所需的查找次数,而类似跳过列表的结构将允许在不全局锁定的情况下写入数据结构。
Evan Plaice 2012年

6

史蒂文·S·斯基埃纳(Steven S.Skiena)编写的《算法设计手册》似乎是您正在搜索的资源。第二部分是对问题的分类列表,并回顾了相关算法。有一个网络版本


3
很棒的书,但不必觉得要真正成为一名程序员就必须掌握所有这本书。我是最近才买的,从1979年起我就开始从事程序设计。(是的,我相信可以从中学到东西,所以买了它。)
Kate Gregory 2012年

@KateGregory我买了这本书,却无法真正掌握它,因为我只知道高级语言,例如Ruby和Javascript(没有二进制树,链接列表等)……我最终放弃了阅读。
bigpotato 2015年

4

没有“应该”。A.熟悉基本的复杂性类(线性,对数等)。B.意识到您可以使用简单的数组几乎完成任何操作,就像使用B树这样的奇特数据结构一样。选择适当的结构/算法的诀窍在于平衡性能,预期的输入大小和实现复杂性。

然后是抽象的但非常有用的东西(尽管用途不是立即显而易见的):状态机,图论,凸性论(线性编程等)。


1
不要低估了知道何时使用什么的重要性。因为您使用一个简单的数组解决的那些问题就会回来,并且在您要使用该大客户并发现可以正常使用多年的应用程序时就咬住了您,而这会因为您使用bubbleort而不是一个快速排序。
Pieter

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.