写一下自己平时学习的一些体会。
今天学的是一般的树。首先是数组实现的树,使用它可以很方便地实现树的并查集算法(父指针法)。
数据结构课开始就讲了数组和链表,这是学习其他数据结构的基础,其他类型的数据结构都先有基于数组的实现方法,然后有些不足,就介绍基于链表的实现方法。(因为链表增删复杂度更低)。
数组不够动态,他一般都固定化了。比如一个一般树的节点一般都要预留足够大的空间,但是这会造成极大的浪费(一个节点有100个孩子,那么数组最少要预留100,但是对于只有2,3个孩子的节点就会造成巨大的浪费)。
实现一般树的方法有子节点法,左子节点/右兄弟节点表示法(有基于数组还有基于链表实现的)。
分析:
首先是介绍子节点法,他就是对于每个父节点都用一个链表来存储他的子节点(子节点连成一串)。但是这种方法对于找节点的兄弟节点比较麻烦(一棵树中与某一节点相关联的节点有父节点,兄弟节点还有子节点,如果他能把他所有相关联的关系都能很好表示出来,并且操作的复杂度比较低,而且没有过多浪费,那就是比价好的设计方法)。
子节点方法中每个父节点的子节点链是由子节点相接而成的,他们相接不就可以表示他子节点之间的兄弟关系吗(兄弟节点才回被连在一个链表中)?但是这种表示方法并没有充分利用这种结构所能表示的其他含义,所以浪费,不节约。而且这种设计方法的链表虽然是可变的,但是最好是定义一个通用的(空间固定的)节点。这样才不会浪费,便于设计。
之前那个没利用好,就是因为我们没从递归方法去思考问题。我们一般的思路存储他的所有孩子,其实只要存储他的有孩子就可以了,因为他的其他孩子不就是他左孩子的右兄弟,所以就可以通过(左孩子的右兄弟)一直递归下去,从而找到他所有的孩子。所以就像是一个链表将所有的东西都串起来,他们不是一种直接关系,而是一种间接(递归的关系)。
所以用递归的思想去思考(链式结构)之后,就有左子节点/右兄弟节点表示法。一个节点只要有三个指针(指向父节点,右兄弟,最左的孩子)就可以了,不但空间统一了。而且也得到了充分的利用。
总结:
像很多这种数据结构,定义中间节点时,要定义一种统一的结构。比如一个节点有100个孩子,而有些节点只有2,3个孩子,我如何把这些混乱统一成一种形式?这就要用到递归的思想和链表的结构。一个节点的孩子就是他最左孩子的右兄弟,然后这个节点的右兄弟,知道节点没有右兄弟为止,这就是他所有的孩子。那么他的兄弟的方法不就是和他子节点的存储和遍历方式一样的吗?所以思维要灵活。
还有就是要把结构之间所能表达的一些关系利用到极致,这样才不浪费空间。
正如老师所说的,有时候解决简单的问题用简单的方法,复杂的问题用复杂的方法,复杂到极致时,就回到了简单的方法,这或许就是大道至简。
我觉得这才是数据结构精华,关键是思想,而不是代码。我们在大学不是学了多少知识,而是你学习方法还有思维,这才是最重要的。所以我对面向对象程序设计思想,算法,数据结构,操作系统很感兴趣。
还记得老师说过的一句话,别人都不愿意做的事,就是门槛所在。
数据结构的感悟-树-学习笔记
最新推荐文章于 2021-05-19 18:41:02 发布