《数据机构与算法分析》(Java语言描述)读书笔记(1)---表

     无论是算法还是数据结构,给人的感觉都像是武林中的内功心法,而具体的编程语言则是外在的招式。没有深厚的内力,外在的招式也无法发挥出应有的威力。这个社会科技给人的感觉真是日新月异,各种让人眼花缭乱的新技术,而我们不应该被外表所蒙蔽,应该看到外边下边一些本质的东西。
         写作是为了更好的思考,所以决定在读书的过程中也留下一些自己的感悟。

        数据结构,可能我们从接触开始,最先接触到的就是表了,分为链表和顺序表,而顺序表被分配的地址在内存空间中连续,其实也就是我们平常使用的数组,只不过在java这边ArrayList 可以使用泛型设计,不仅可以存储基本的数据类型,也可以存储对象的引用。书中一开始提到了ADT(抽象数据类型),解释为带有一组操作的一些对象的集合。我对这个概念的理解就是,其实在java中就是一些对象而这些对象是用来存储数据的,带有像增删改查这样的操作。为什么叫抽象,就是我们不必知道他们具体的实现,直接调用增删改查这样的操作来操作数据。         

比较一下链表和顺序表的优缺点:

1:查找 

顺序表明显是在这方面占有优势,知道具体的index就能直接找到所找位置。链表没有索引,所以只能顺着头部或者尾部开始一个节点一个节点这样找下去。

2:添加,删除 

这个其实是选择两种不同表的依据。如果是顺序表的话,插入的位置,和删除的位置对时间的开销影响很大,因为顺序表是连续 分配的内存空间,所以他们每个元素之间必须连续,这样如果删除了开头位置的元素,之后位置上的所有元素都要向上移动,如果添加删除在末尾发生,代价就很小了。 而链表此时的优点就显现出来了,因为每个节点在内存中的地址不一定连续,这样添加和删除过程只需改变两个节点之间链的  指向,代价就会很小。而顺序表一旦元素数量超过了一开始分配的空间,就要扩充空间这样代价也是很大的,需要把原来的顺序表复制到一个新的顺序表中,而链表只需要生成新的节点进行添加就ok了。                                                            *********************************************************************************         

       java.util 这个包中直接为我们提供了ArrayList类,和LinkedList这两个类。根据文档很容易学会这两个类的使用方法。而这本书中着重介绍的不是这两个类的使用方法,而是这两种数据结构的实现方法。这里说明一下这两种数据结构实现过程中用到的方法。这两个类的实现过程中都用到了迭代器,Iterator其实就是一个java的接口,实现了这个接口就可以对集合进行简单的遍历。而接口其实就是一种规约,规定了名字却没有具体实现,把实现这个接口的工作交给完成这个接口的子类。所以如果我自己去分别           实现ArrayList 和 LinkedList那么对于iterator中的hasNext()方法,具体的实现方法是不一样的。并且接口类型的变量可以存储实现这个接口的子类,这样对client就可以做到信息的屏蔽,每次发生改动,client端的代码不需要修改,他们仍然调hasNext()    方法。因为代码有点长,暂时没有找到源码,就不贴出来了,有书的可以自己对照着书看。

      说一下要点:

1:在MyArrayList 和MyLinkedList 当中分别用了一个内部类ArrayListIterator和LinkedListIterator 实现Iterator 接口,这样根据两个连表的不同特点用不同的方法去实现接口中的方法。这里提到了内部类,内部类最常见的地方应该是在设定监听器的时候,语法确实有些古怪。我们可以把这个内部类看成是外部类的一个成员变量,如果把内部类设置成private 那么内部类当中的属性设置成private 或者public 都无所谓,因为这个内部类不被外部类以外 的任何类可见,当然也就谈不上去获取内部类的属性了。而内部类对外部类的属性和方法是具有可见性的。这样就可以通过这个接口对list中的元素进行操作了。       

2:在设计这个MyLinkedList 过程中考虑了一种情况就是,在我们调用next()方法去获取下一个节点时,恰好下一个节点被删除,或者被添加。一开始我觉得添加或者删除了,继续返回新的不就可以了。后来发现这是iterator使用过程中要注意的一点,就iterator  remove的是next()返回的项,必须再次调用next()然后才能调用remove,目前还不大明白java这样设计的目的,应该是有它的优点的。那么为了防止这种在迭代过程中发生添加删除,所以在MyLinkedList中就用一个modCount 来记录这个List同时在内部类LinkedListIterator 中也保存有一个modCount 每次发生add remove clear 的时候就增加该flag的值,同时再设置一个flag叫okToRemove 这个值在remove 后设置为false 然后发生过next()之后再设置为true,这样就保证每一次remove都发生在next()后边,就符合该接口的要求了。其实在MyLinedList当中有好几个重载的remove方法,Iterator的remove方法不带参数, 所以在调用Iterator的remove方法时要检测是否调用了外部类的remove(parameter)方法,所以外部类每次add或者remove都要改变modCount,所以检测LinkedListIterator中的modCount 和外部类的modCount是否一致,如果一致,说明没有通过外部类         的remove方法进行添加删除,而调用Iterator的remove方法其实是调用外部类的remove方法,这样内外部类的modCount会一     直保持一致。

      其实我们没必要去自己实现一个链表顺序表,而这种检错方法使我们可以借鉴的。没想到一个简单的表中间能挖掘出这么多隐藏的东西,书果然需要耐心的读,坚持!         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值