基于Java的双循环链表查询
下面是取自的代码,其中包含方法基于Java的双循环链表查询,java,data-structures,doubly-linked-list,Java,Data Structures,Doubly Linked List,下面是取自的代码,其中包含方法 next()prev()insertAfter()insertBefore()和remove() 方法需要用溶液填充 在考虑填写解决方案之前,我想问一下,如果DList类的用户将DListNodetype对象传递给上述5种方法,那么DListNode抽象数据类型是否会损坏。因为DList类如何确保该DListNode类型节点是否真的是列表的一部分 /* DList.java */ package list; /** * A DList is a mutab
next()
prev()
insertAfter()
insertBefore()
和remove()
方法需要用溶液填充
在考虑填写解决方案之前,我想问一下,如果
DList
类的用户将DListNode
type对象传递给上述5种方法,那么DListNode
抽象数据类型是否会损坏。因为DList
类如何确保该DListNode
类型节点是否真的是列表的一部分
/* DList.java */
package list;
/**
* A DList is a mutable doubly-linked list ADT. Its implementation is
* circularly-linked and employs a sentinel (dummy) node at the head
* of the list.
*
* DO NOT CHANGE ANY METHOD PROTOTYPES IN THIS FILE.
*/
public class DList {
/**
* head references the sentinel node.
* size is the number of items in the list. (The sentinel node does not
* store an item.)
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
*/
protected DListNode head;
protected int size;
/* DList invariants:
* 1) head != null.
* 2) For any DListNode x in a DList, x.next != null.
* 3) For any DListNode x in a DList, x.prev != null.
* 4) For any DListNode x in a DList, if x.next == y, then y.prev == x.
* 5) For any DListNode x in a DList, if x.prev == y, then y.next == x.
* 6) size is the number of DListNodes, NOT COUNTING the sentinel,
* that can be accessed from the sentinel (head) by a sequence of
* "next" references.
*/
/**
* newNode() calls the DListNode constructor. Use this class to allocate
* new DListNodes rather than calling the DListNode constructor directly.
* That way, only this method needs to be overridden if a subclass of DList
* wants to use a different kind of node.
* @param item the item to store in the node.
* @param prev the node previous to this node.
* @param next the node following this node.
*/
protected DListNode newNode(Object item, DListNode prev, DListNode next) {
return new DListNode(item, prev, next);
}
/**
* DList() constructor for an empty DList.
*/
public DList() {
this.head = new DListNode(Integer.MIN_VALUE, null, null);
this.head.next = this.head;
this.head.prev = this.head;
this.size = 0;
}
/**
* next() returns the node following "node" in this DList. If "node" is
* null, or "node" is the last node in this DList, return null.
*
* Do NOT return the sentinel under any circumstances!
*
* @param node the node whose successor is sought.
* @return the node following "node".
* Performance: runs in O(1) time.
*/
public DListNode next(DListNode node) {
if(node.next != this.head){
return node.next;
}else{
return null;
}
}
/**
* prev() returns the node prior to "node" in this DList. If "node" is
* null, or "node" is the first node in this DList, return null.
*
* Do NOT return the sentinel under any circumstances!
*
* @param node the node whose predecessor is sought.
* @return the node prior to "node".
* Performance: runs in O(1) time.
*/
public DListNode prev(DListNode node) {
if(node.prev != this.head){
return node.prev;
}else{
return null;
}
}
/**
* insertAfter() inserts an item in this DList immediately following "node".
* If "node" is null, do nothing.
* @param item the item to be inserted.
* @param node the node to insert the item after.
* Performance: runs in O(1) time.
*/
public void insertAfter(Object item, DListNode node) {
//Your solution here
/*if(node != null){
node.next = new DListNode(item, node, node.next);
node.next.next.prev = node.next;
}*/
}
/**
* insertBefore() inserts an item in this DList immediately before "node".
* If "node" is null, do nothing.
* @param item the item to be inserted.
* @param node the node to insert the item before.
* Performance: runs in O(1) time.
*/
public void insertBefore(Object item, DListNode node) {
// Your solution here.
}
/**
* remove() removes "node" from this DList. If "node" is null, do nothing.
* Performance: runs in O(1) time.
*/
public void remove(DListNode node) {
// Your solution here.
}
/**
* toString() returns a String representation of this DList.
*
* DO NOT CHANGE THIS METHOD.
*
* @return a String representation of this DList.
* Performance: runs in O(n) time, where n is the length of the list.
*/
public String toString() {
String result = "[ ";
DListNode current = head.next;
while (current != head) {
result = result + current.item + " ";
current = current.next;
}
return result + "]";
}
}
我的问题:
DList
类如何确保传递给上述方法的DListNode
类型节点是否为真节点?通过传递节点,我们是否有机会打破前面提到的DList
ADT的不变量?类DList
的用户可以只传递项而不是传递节点,但用户需要访问节点以避免N^2算法在他身边。因此,用户可以操作项
,但不能操作上一个
和下一个
引用。当用户使用这5种方法之一时,比较整个列表中传递的节点以检查真正的节点也没有意义。因为这是一个代价高昂的操作,所以代码的“安全”或“不安全”与您所做的完全相同。它可以写得完全偏执,完全未经检查,或者可以包含一些基本检查以捕获大多数使用错误。这取决于你。我没有得到你的答案。你们的意思是,若不进行检查,那个么列表就有可能被破坏。如果检查完成,那么这5项操作将是一件昂贵的事情?代价有多大取决于您,取决于您的聪明才智。
/* DListNode.java */
package list;
/**
* A DListNode is a node in a DList (doubly-linked list).
*/
public class DListNode {
/**
* item references the item stored in the current node.
* prev references the previous node in the DList.
* next references the next node in the DList.
*
* DO NOT CHANGE THE FOLLOWING FIELD DECLARATIONS.
*/
public Object item;
protected DListNode prev;
protected DListNode next;
/**
* DListNode() constructor.
* @param i the item to store in the node.
* @param p the node previous to this node.
* @param n the node following this node.
*/
DListNode(Object i, DListNode p, DListNode n) {
this.item = i;
this.prev = p;
this.next = n;
}
}