HW5一开始做不出来的同学可以继续先看Lecture,Encapsulated List那一节老师会回顾一下HW5,对作业有启发思路的作用。
Part1.
HW5的DListNode增加一个myList的field,用于确认node位于哪个list,同时也为后面的isValidNode()服务。
remove()之后需要将myList, prev, next 统统指向null,不然这个node的prev和next仍指向前后,后导致后面如果insertAfter出错。
Part2.
insert(), union(), intersection()等方法中的对比需要使用compareTo(), 因为求并交集时要比较字典序lexicographically,比如“3”在“5”的前面还是后面。回顾一下==, .equals(), compareTo()的用法
a==b | 比较a和b是否指向同一个object |
a.equals(b) | 验证a和b是否相等。允许a.equals(null) |
a.compareTo(b) | 比较a和b的字典序,1. a<b, 返回负数; 2.a=b,返回0; 3.a>b,返回正数. a.compareTo(null)会返回NullPointException |
DListNode
/* DListNode.java */
package com.homework5;
/**
* A DListNode is a mutable node in a DList (doubly-linked list).
**/
public class DListNode extends ListNode {
/**
* (inherited) item references the item stored in the current node.
* (inherited) myList references the List that contains this node.
* prev references the previous node in the DList.
* next references the next node in the DList.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
**/
protected DListNode prev;
protected DListNode next;
/**
* DListNode() constructor.
* @param i the item to store in the node.
* @param l the list this node is in.
* @param p the node previous to this node.
* @param n the node following this node.
*/
DListNode(Object i, DList l, DListNode p, DListNode n) {
item = i;
myList = l;
prev = p;
next = n;
}
/**
* isValidNode returns true if this node is valid; false otherwise.
* An invalid node is represented by a `myList' field with the value null.
* Sentinel nodes are invalid, and nodes that don't belong to a list are
* also invalid.
*
* @return true if this node is valid; false otherwise.
*
* Performance: runs in O(1) time.
*/
public boolean isValidNode() {
return myList != null;
}
/**
* next() returns the node following this node. If this node is invalid,
* throws an exception.
*
* @return the node following this node.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public ListNode next() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("next() called on invalid node");
}
return next;
}
/**
* prev() returns the node preceding this node. If this node is invalid,
* throws an exception.
*
* @return the node preceding this node.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public ListNode prev() throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("prev() called on invalid node");
}
return prev;
}
/**
* insertAfter() inserts an item immediately following this node. If this
* node is invalid, throws an exception.
*
* @param item the item to be inserted.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public void insertAfter(Object item) throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("insertAfter() called on invalid node");
}
// Your solution here. Will look something like your Homework 4 solution,
// but changes are necessary. For instance, there is no need to check if
// "this" is null. Remember that this node's "myList" field tells you
// what DList it's in. You should use myList.newNode() to create the
// new node.
DListNode new_node = ((DList)myList).newNode(item,(DList)myList,this,this.next);
this.next.prev = new_node;
this.next = new_node;
this.myList.size++;
}
/**
* insertBefore() inserts an item immediately preceding this node. If this
* node is invalid, throws an exception.
*
* @param item the item to be inserted.
* @exception InvalidNodeException if this node is not valid.
*
* Performance: runs in O(1) time.
*/
public void insertBefore(Object item) throws InvalidNodeException {
if (!isValidNode()) {
throw new InvalidNodeException("insertBefore() called on invalid node");
}
// Your solution here. Will look something like your Homework 4 solution,
// but changes are necessa