所以我是计算机科学专业的学生,大约一个星期左右......我将重新学习数据结构课程,使用C ++来应用理论。是的,我确实说过“重拍”。去年秋天我参加了课程,我觉得还有更多需要学习的东西。作为一名学生,我觉得我必须了解基础知识,因为通过已经了解基本概念来理解未来课程中的新概念会更容易......不必每次都重新学习。
第一次,我没有C ++经验,课程期望我们在第一周结束时编写代码。我努力完成了几个最初的编程任务(MP)。毋庸置疑,我已经习惯了,并且在学期的剩余时间里对语法没有什么困难。但随后更难的数据结构出现了,理论(Big O)成为了困难的部分。
总而言之,这是一次很棒的经历,但我觉得我的问题是我没有养成良好的学习习惯。我做了国会议员并出席了演讲,但似乎我心里不在乎。我想第二次改变这个,因为回顾课程,我确实度过了愉快的时光,我很喜欢这些材料。但是当我需要花时间考虑如何有效地使用数据结构时,我发现自己花了太多时间考虑/建立数据结构。
学习理论很难(主要是因为它不那么令人兴奋)所以我应该如何应用自己来真正理解数据结构所涵盖的类?我一直是一个视觉学习者,一个互动的学习者......我不想花时间做我的议员。相反,我想花时间以这种方式让我真正学习/理解概念,然后直接应用知识。
我正在寻找任何建议......或许在过去学习这些概念的学习习惯的建议......或者关于良好记笔记技巧的建议......你想做的任何事情分享:) ...最重要的是,如何在学期开始前准备。
即使选择了答案,也请随时提供反馈。我正在寻找你的建议......这就是我发布的原因:)谢谢!
注意:课程中涵盖的数据结构和主题:列表,堆栈,队列,树(不同种类),哈希表,图表,搜索/排序/遍历技术。
更新:这是目前为止从答案中汇编的链接和参考文献列表。
更新2 :以下是我发现的更多来源列表:
答案 0 :(得分:21)
您已收到一些有趣的链接和想法。我希望我能提供一些不同的观点:
通过教导计算机内存就像一个很长的列表,我学会了可视化和“喜欢”数据结构。然后,结构在存储器中具有不同的布局。通过可视化记忆中的结构,我(以及有趣的)它们如何工作变得显而易见。了解内存中的数据布局对于程序员来说非常重要,因为今天不断增长的机器通常会被内存访问所阻止。良好的内存布局减轻了CPU从内存中获取数据的负担,因此CPU不必等待数据到达。
数据结构是内存中数据的布局。将内存视为一个长列表,就像购物清单但没有条目。
0...
1...
2...
3...
4...
5...
6...
当你将结构放入内存时,它们基本上会填充内存中的这些插槽。
列表非常简单,它只是从顶部和底部填充内存列表:
0 Element 0
1 Element 1
2 Element 2
3 Element 3
虽然有时您想要将元素2更改为其他内容,但可能为零。这就是列表工作的方式。您可以通过了解其索引来访问结构中的数据(在本例中为0 .. 3)。
堆栈不同。您只能通过将元素“推”到其顶部来访问堆栈的“顶部”,或者从其顶部“弹出”元素。推动意味着添加另一个元素,旧的顶部变得不可见。弹出意味着移除顶部元素,其下方的元素变得可见。
0 [ Hidden data ]
. [ Hidden data ]
. [ Hidden data ]
. [ Hidden data ]
n [ Hidden data ]
n+1 Element 4
链接列表不同。链表包含数据的指针(内存列表中的索引)和指向下一个元素的指针:
0 Data: Memory index 0x00000100
1 Next: Memory index 6
2
3
4
5
6 Data: Memory index 104
7 Next: Memory index 8
...
100 Data pointed to from first member
101
102
103
104 Data pointed to from second member
队列就像一个更强大的堆栈,你可以访问底部和顶部。您只能将项目推到顶部,而您只能从底部弹出项目。
0 (bottom) Element (ready to be popped)
1 [ Hidden data ]
2 [ Hidden data ]
3 [ Hidden data ]
.
.
.
n (top) (empty, ready to be pushed / be given data)
通过可视化每个数据结构的布局,对于我们如何需要内存以及它们如何工作(也在内存中),它们变得更加明显。我希望我的例子能为您提供一些简短的入门知识,为您的未来研究奠定基础。作为数据结构的最后一个例子,我将给你一个不平衡的二叉树,它具有以下元素插入顺序: 3,2,1,10,9,8,6,5,4,7
树从内存地址100开始,因为内存地址0无效,我将其用作“无指针”。
100 Value: "3"
101 Left ptr: 103
102 Right ptr: 109
103 Value: "2"
104 Left ptr: 106
105 Right ptr: 0
106 Value: "1"
107 Left ptr: 0
108 Right ptr: 0
109 Value: "10"
110 Left ptr: 112
111 Right ptr: 0
112 Value: "9"
113 Left ptr: 115
114 Right ptr: 0
115 Value: "8"
116 Left ptr: 118
117 Right ptr: 0
118 Value: "6"
119 Left ptr: 121
120 Right ptr: 127
121 Value: "5"
122 Left ptr: 124
123 Right ptr: 0
124 Value: "4"
125 Left ptr: 0
126 Right ptr: 0
127 Value: "7"
128 Left ptr: 0
129 Right ptr: 0
希望有所帮助!
答案 1 :(得分:17)
这对我帮助最大...... 由于你是一个视觉人,谷歌有一些可视化的排序算法,树遍历,散列等,以便大致了解正在发生的事情。在那之后,尝试使用不同的结构制作一个简单的程序,并尝试不同的排列 - 例如,你可以创建一个链表开始,然后使它成为一个循环链表,然后使其成为一个双向链表,然后把它变成一个双循环链表,等等......
您只需要对结构进行试验,当您这样做时,您将开始看到哪些数据结构适合您将要开发的应用程序。
以下是一些很好的参考资料.. 排序算法:http://www.sorting-algorithms.com/树遍历:http://nova.umuc.edu/~jarc/idsv/lesson1.html图遍历:http://www.cosc.canterbury.ac.nz/mukundan/dsal/GraphAppl.html
关于效率(大O分析),一旦你理解了数据结构的每个操作的算法级别发生的事情,它或多或少会自然而然地产生。
我的大学强调的一件事是开发我们自己的数据结构实现(这是自下而上的学习),而不是潜入预先建立的C ++模板(自上而下的学习)。通过从头开始,您真正了解插入,删除,搜索(遍历)和访问某个结构中的数据所涉及的开销,这将有助于您在将来设计系统时的直觉。
答案 2 :(得分:9)
练习,练习,练习。
我给你的第一条建议是尽可能熟练地使用C ++。
数据结构和编程是两个截然不同的主题。如果您发现自己在编程方面苦苦挣扎,那么您就不太可能理解数据结构。
你如何熟练掌握C ++?实践,实践,实践。编程一切。了解有关它的一切。写几十个小程序。你可以做些什么来适应C ++。
如果您熟练掌握C ++,那么我向您保证数据结构将变得更加容易。 (请注意,我说的不容易,我说更容易:))
答案 3 :(得分:5)
学习数据结构的关键是从一些小的东西开始,然后在此基础上构建。让我们从一个简单的C
结构开始:
struct Person {
char name[100];
int age;
};
此数据结构代表一个人。你需要确保你理解这些简单的结构概念,然后你可以转向更大的东西。
例如,当您开始讨论堆栈和队列等数据结构时,首先尝试从概念上理解数据结构正在做什么。例如,对于堆栈,我们使用LIFO原则,即Last In First Out。使用队列,我们使用FIFO原则(先进先出)。
然后就是那个绊倒很多人的链接列表。你需要很好地理解这个指针,所以在尝试解决链表之前,先从简单的事情开始:
int* x;
int y = 10;
x = &y;
您应该能够查看该代码并立即知道它正在做什么。如果你做不到,那么你还没准备好转向更高级的数据结构,比如链接列表。
我要做的主要观点是你需要将基础知识降低,然后再建立基础。同样非常重要的是要非常努力地跟上课程,如果你遇到麻烦,请问你的老师或导师,并确保你每周都走上正轨并且不落后。
计算机科学课程很像数学课程,每周通常建立在你从前N周学到的所有东西上。因此,如果你不理解一个关键概念,例如指针,那么你将在本学期的剩余时间内进行重大的挣扎。
答案 4 :(得分:5)
我喜欢dcp的答案。
围绕数据结构的最佳方法是编写迷你示例。即使你从书中复制它们,如果你可以让它们工作和编译,并且你用自己的手指输入它们,你将会学到很多东西。
当您阅读本书时,在每次讲座之后,编写您可以创建和使用(显示,使用等)您刚刚学习的数据结构的最短程序。
然后,当你必须完成实际作业时,你会学到更多,当你尝试拿出你的小例子并将它们插入解决作业问题时。
我认为为各个数据结构编写最短/最小的工作代码非常有用。此外,不要害怕复制代码(为了你自己的启发,而不是你的转身分配)....如果你通过打字复制而不是复制粘贴,你最终学习了很多,因为它迫使你查看代码中的每个字符。
如果整个数据结构看起来“太多”无法绕开,那么首先编写数据结构组件的迷你示例。所以用指针存储书名。然后存储许多带有指针指针的书名。使用方括号表示法和指针算法读取书名。在简单的函数中使用递归,其中很明显发生了什么.....例如,递归以显示数字的阶乘更简单地包围你而不是递归以显示二叉树(在我看来)... ..
你会看到你的问题区域是什么,并尝试将它们分离为尽可能小的特定事物,然后写一个可以处理该问题区域的程序。然后建立。
你的讲座是关于整个数据结构......巨大的Cummulus是理论上的银行......所以,基本上它们是自上而下的。在小问题中隔离语法和用法的小问题是自下而上的。所以你的老师会帮助你从顶部进行攻击,你通过练习从底部进行攻击,很快中间就没有任何东西了!
答案 5 :(得分:3)
有意义地学习数据结构和算法的唯一方法是将它们应用于现实世界的问题并使用它们来解决实际问题。将它们编入工作应用程序 - 即使它们设计 - 将加强理论知识,使您更有机会保留这些想法并将它们整合到您的个人解决问题的方法中。
答案 6 :(得分:3)
您需要记住的一件事是数据结构不仅存在。它们的发明是为了满足需要,因此这意味着它们出于某些原因是好的,但对其他原因则不然
找出这些原因是什么,数据结构有什么用处,在告诉他们之前,尝试找出操作的大O.
始终比较数据结构。即使是最简单的 - 阵列。以此为出发点,将您找到的每个数据结构与数组进行比较。有时你会发现一些小技巧可以帮助你完全避免使用大数据结构
对我来说,有什么帮助我理解了很多数据结构和算法,这里有applet,我希望它对你也有所帮助:Applet
答案 7 :(得分:3)
我建议你写一本关于算法的好书(Cormen等人的“算法导论”将是我的推荐)。通过本书,您将开发并使用不同的数据结构,您很可能会意识到每个结构的优点。数据结构仅作为实现不同目标的手段:解决特定问题。
根据您拥有或想要花费多少时间,您可以尝试从ACM ICPC等不同的编程竞赛中获取问题。大多数问题都需要你运用这些知识。请注意,算法和数据结构都是语言无关的,因此如果您对其他语言有很好的了解,请使用它。
答案 8 :(得分:3)
在我看来,这些事情在在职或通过经验学习比在理论课程中学习更好。大多数时候,当我在学校时,努力保持领先于曲线是重要的部分,我认为这与你经历的经历类似。虽然你想要彻底理解它是值得称赞的,但只要你知道在需要的时候在哪里找到好的参考资料,那么课程就达到了目标。
大多数课程都将建立在过去课程中获得的知识基础之上。您将在学习中再次遇到这些细节,您的教授应该能够帮助您将过去学到的知识应用到当前的课堂作业中。作为一个互动学习者,办公时间,实习和导师机会似乎是获得所需信息的更好方式。
祝你好运!答案 9 :(得分:2)
答案 10 :(得分:2)
当我教编程时,我总是将揭秘的书籍推荐给我的学生。
我建议你阅读:
- Data Structures Demystified
- OOP揭秘了
这两本书以简单易懂的术语分解数据结构和OOP原理,并且易于理解。这是一个很好的概述,但它没有涉及STL提供的数据结构。
答案 11 :(得分:2)
老实说,我最初是一名自学成才的C ++程序员(我的主要参考资料是来自Half-Life 2的Source游戏引擎的公共域代码),并且我通过绘制了解了很多通过数据结构得到的东西图表和阅读评论和代码。
也许我只是一个神童或者某种东西,因为它似乎对我来说似乎相对容易,但我在很长一段时间里学习了阅读,思考和分析每种结构的特定用途,以及为什么每个结构首先作为与其他数据结构分开的东西存在。
在高中严格限制的TI-83 Plus计算器上编写了一些严肃的代码项目(即Connect Four和侧滚动太空射击游戏,以及3D等距绘图仪和2D绘图程序)(ps使用TI -Basic, not Assembly),我意识到什么样的操作更有效率,我意识到内置列表系统(基本Vector)在某些情况下对数据存储的限制。当我尝试使用不同大小的输入列表计算程序的运行时间时,我也想出了Big-O是如何工作的。
练习,思考你正在做的事情,并试着弄清楚它们是如何以及为什么起作用的,并且永远不要害怕因为测试而沮丧。毕竟,没有实验的科学是什么?
答案 12 :(得分:2)
不确定这是否有任何帮助,但确实有点令人鼓舞。
4年前,当我参加Data Structures时,我就在同一条船上。我经历了足够的知识课程,至少在课堂上获得了B,尽管我对它并不了解很多。
我不明白模板,链接列表,'这个'指针,并且真的一般都不理解指针那么好,这极大地阻碍了我的能力。我奇迹般地完成了作业和测试所需要的东西(尽管每个人的考试成绩仍然很低,而我的老师让他们弯曲了)并完成了B。
之后我继续上了几年的其他课程。我发现在这些课程中,不同的概念是分开教授的,这有助于我更好地理解它们。算法更多地讲述了排序和Big O,汇编更多地讲述了计算机“引擎盖下”的内容,这些内容帮助我理解指针等。
我意识到我第五年的第二个学期的第二个学期我非常了解数据结构中的所有概念,我甚至没有花费任何额外的努力来学习它们,至少从回归和尝试的角度来看特别是为了理解数据结构,如果这有意义的话。
在没有任何实际努力的情况下,我最终编写了一个模板化的,链接列表堆栈和队列,用于操作系统中的几个家庭作业,我理解它们。它让我感到震惊。我很肯定你会这样。给它时间并专注于其他类,它将全部点击。对我来说似乎需要永远点击,但确实如此。
希望有所帮助。
答案 13 :(得分:2)
我记得我的第一个数据结构课程。我记得起初有点不知所措。
我更像是一个视觉学习者。为了更好地掌握材料,它确实有助于看到图片。我曾经绘制过插入,删除和迭代数据结构(如链表或队列)的步骤。在我完成之前它占用了大量纸张,但它非常值得。
一旦我开始绘制插入过程和什么不是,实际编程数据结构的过渡要容易得多。
能够可视化内存中发生的事情确实有帮助。并且,正如其他人在我之前提到的:练习,练习,练习!
成功的重要部分。
祝你好运!答案 14 :(得分:2)
一个好的资源是The NIST Dictionary of Algorithms and Data Structures。你不会坐下来记住所有这些信息,你不应该使用它来避免编码你自己的结构,这将完全取消该类的价值,但这个网站作为一个很好的参考,因为它链接数据结构与使用它们的算法,并显示一些变体,提供了如何修改结构以供其他用途的见解。
希望有所帮助。祝好运。
答案 15 :(得分:2)
如果您是视觉学习者,请向教师咨询更多图表。您可以询问其他学生是否可以与他们一起学习。也许其中一个人可以用一种你可以更容易掌握的方式向你解释事情
答案 16 :(得分:2)
这是一篇很好的文章,可以帮助您入门:http://www.codeproject.com/KB/cpp/linked_list.aspx。使用简单的链接列表启动。它非常简单,您将比其他数据结构更容易理解它。堆栈和队列可能在概念上更容易,但它们基于简单的链表。然后,您可以移动到双链表和树。期待看到您的编码问题,祝您好运! :)
答案 17 :(得分:2)
如果您能够在现实生活中可视化数据结构的实现,或者解决现实生活中的问题,那么您可能会发现它更容易理解。
以下是一些
答案 18 :(得分:1)
实际上,我发现数据结构需要对指针和内存有充分的理解。
例如,您应该能够了解以下链接列表在一分钟内无法正常工作的原因。
但是,要理解为什么它不起作用,你必须理解如何在C和C ++中布局内存,并直观地理解指针的概念。
有些人喜欢照片和画画。其他人喜欢观看麻省理工学院开放式课程 - 我建议至少尝试一下。
class node
{
int data;
node* next;
node* addnode()
{
node newnode;
this->next = &newnode;
return &newnode;
}
};
这是我在10年前学习数据结构时写的链表的(有问题的)实现的近似。
作为最后一点,实践和理论是高质量程序员/开发人员/计算机科学家的阴阳。没有两者,你不可能真正精通。
答案 19 :(得分:1)
如果你有O符号的问题,那么Cormen et.al的“算法简介”。以易于理解的方式介绍这些理论概念。好吧,这本书基本上是基础数据结构的圣经。运行时/空间界限的证明总是以非常有教育意义的方式呈现。
与往常一样,如果你学习这样的书,不要只是阅读它,而是尝试在大多数练习上学习。通常,这样做对于学习这些东西非常有效。
另一种通用技巧:尝试加入一个由2-3名其他学生组成的当地学习小组 - 通常,与他人讨论这些材料(面对面),同时尝试向同伴解释自学材料,这会给你带来很多提示,你需要涵盖的更多内容。
要掌握练习的C ++,Stroustrup的“C ++编程语言”对各种语言概念进行了很好的介绍和参考。由于C ++是一种多范式语言,初学者常常会混淆实际用于解决某些问题的概念。为了帮助Scott Myers提供的“有效的C ++”,这是一个良好的开端。
如果你的课程大量使用STL,那么也有'有效STL'。斯科特迈尔斯的写作风格通常被认为是非常适合初学者。
答案 20 :(得分:1)
对我而言,我发现(迄今为止)用于理解数据结构的最好的书是Steven Skiena的The Algorithm Design Manual。 除了第一部分覆盖算法分析,算法&数据结构第二部分对于找到(或至少缩小)用于解决问题的适当数据结构/算法绝对是无价的。