CS61b homework5
hw5相比hw4,修改了以下的bug,从而更好的实现了对代码的封装:
1:hw4中,remove(n)时,若n不存在于本list却存在于其他list中,会remove其他list中的node,同时减少本list的size。
2:hw5中,listnode本身含有其所包含的list的field,因此可将insertAfter()等方法移到listnode中实现。
3:hw4中,如果在remove(n)后实现insertAfter(n),由于remove后n依然存在,会产生插入的错误。
4:hw4中,如果遍历至最后node会返回null,hw5中遍历到最后会抛出InvalidNodeException,更方便查找错误。
part1实现结果(以后直接贴代码好了,截图好麻烦):具体实现类似hw4,注意抛出异常。
An empty list should be [ ]: [ ] l.isEmpty() should be true: true l.length() should be 0: 0 Finding front node p of l. p.isValidNode() should be false: false p.item() should throw an exception, and did. p.setItem() should throw an exception, and did. p.next() should throw an exception, and did. p.prev() should throw an exception, and did. p.insertBefore() should throw an exception, and did. p.insertAfter() should throw an exception, and did. p.remove() should throw an exception, and did. Finding back node p of l. p.isValidNode() should be false: false p.item() should throw an exception, and did. p.setItem() should throw an exception, and did. p.next() should throw an exception, and did. p.prev() should throw an exception, and did. p.insertBefore() should throw an exception, and did. p.insertAfter() should throw an exception, and did. p.remove() should throw an exception, and did. l after insertFront(10) should be [ 10 ]: [ 10 ] l is a list of 3 elements: [ 1 2 3 ] n.item() should be 1: 1 n.item() should be 2: 2 n.item() should be 2: 2 n.item() should be 4: 4 n.item() should be 3: 3 n.item() should be 6: 6 After doubling all elements of l: [ 2 4 6 ] p.isValidNode() should be false: false p.item() should throw an exception, and did. p.setItem() should throw an exception, and did. p.next() should throw an exception, and did. p.prev() should throw an exception, and did. p.insertBefore() should throw an exception, and did. p.insertAfter() should throw an exception, and did. p.remove() should throw an exception, and did. n.item() should be 6: 6 n.item() should be 12: 12 n.item() should be 4: 4 n.item() should be 8: 8 n.item() should be 2: 2 n.item() should be 4: 4 After doubling all elements of l again: [ 4 8 12 ] p.isValidNode() should be false: false p.item() should throw an exception, and did. p.setItem() should throw an exception, and did. p.next() should throw an exception, and did. p.prev() should throw an exception, and did. p.insertBefore() should throw an exception, and did. p.insertAfter() should throw an exception, and did. p.remove() should throw an exception, and did. Removing middle element (8) of l: 8 l is now: [ 4 12 ] p.isValidNode() should be false: false p.item() should throw an exception, and did. p.setItem() should throw an exception, and did. p.next() should throw an exception, and did. p.prev() should throw an exception, and did. p.insertBefore() should throw an exception, and did. p.insertAfter() should throw an exception, and did. p.remove() should throw an exception, and did. Removing end element (12) of l: 12 l is now: [ 4 ] p.isValidNode() should be false: false p.item() should throw an exception, and did. p.setItem() should throw an exception, and did. p.next() should throw an exception, and did. p.prev() should throw an exception, and did. p.insertBefore() should throw an exception, and did. p.insertAfter() should throw an exception, and did. p.remove() should throw an exception, and did. Removing first element (4) of l: 4 l is now: [ ] p.isValidNode() should be false: false p.item() should throw an exception, and did. p.setItem() should throw an exception, and did. p.next() should throw an exception, and did. p.prev() should throw an exception, and did. p.insertBefore() should throw an exception, and did. p.insertAfter() should throw an exception, and did. p.remove() should throw an exception, and did.
part2:
学习了用list求交集合并集的方法,一开始求uinion的时候想着直接把s集合的node挨个insert进来就行了,后来发现作业要求中不让这么干,因为这样时间复杂度正比于size1*size2,
后来还是看了地里的讨论帖才想明白是怎么回事。由于两个set本来就是sort好的,所以union的时候只需要将s中的每个node和本集合比较,小了则insertBefore,大了就和后面的继续比较,相等的话无动作,下一个s中的node可以从上一个node比较结束的位置开始,这样时间复杂度就可以正比于size1+size2,intersect同理,具体实现有一些不同.,另外需要考虑到两个集合元素遍历到末尾时的特殊情况。
代码:
uinion:
public void union(Set s) { ListNode snode=s.list.front(); ListNode thisnode=this.list.front(); try{ while(snode.isValidNode()){ Comparable external=(Comparable)snode.item(); Comparable internal=(Comparable)thisnode.item(); if(external.compareTo(internal)<0){ thisnode.insertBefore(external); thisnode=thisnode.prev(); snode=snode.next(); this.number++; } else if(external.compareTo(internal)>0){ if(!thisnode.next().isValidNode()){ thisnode.insertAfter(external); number++; } thisnode=thisnode.next(); } else if(external.equals(internal)){ if(!thisnode.next().isValidNode()){ snode=snode.next(); } else{ thisnode=thisnode.next(); snode=snode.next(); } } } }catch(InvalidNodeException e){ e.printStackTrace(); } }
intersect:
public void intersect(Set s) { ListNode thisnode=this.list.front(); ListNode snode=s.list.front(); try{ while(thisnode.isValidNode()){ if(!snode.isValidNode()){ ListNode node=thisnode; thisnode=thisnode.next(); node.remove(); this.number--; } else{Comparable internal=(Comparable)thisnode.item(); Comparable external=(Comparable)snode.item(); if(external.compareTo(internal)<0){ snode=snode.next(); } else if(external.compareTo(internal)>0){ ListNode node=thisnode; thisnode=thisnode.next(); node.remove(); this.number--; } else if(external.equals(internal)){ thisnode=thisnode.next(); snode=snode.next(); } } } }catch(InvalidNodeException e){ e.printStackTrace(); } }
运行结果:
Set s = {3,4,} Set s2 = {4,5,} Set s3 = {3,5,8,} After s.union(s2), s = {3,4,5,} After s.intersect(s3), s = {3,5,} s.cardinality() = 2