【发布时间】:2020-03-24 16:12:45
【问题描述】:
我正在尝试学习并有一个关于集合中的递归方法的问题,我在这里读到:
“当使用递归方法实现集合类时,我们通常必须为每个操作编写一对方法。 第一种方法是接口中指定的公共方法。它可以迭代或递归编写。它是迭代编写的,它只是调用... 第二种方法,它是一个私有静态方法,可以完成所有工作。
例如,假设我们正在通过一个链表实现一个通用优先级队列(LN 将值存储为一个对象),使用一个前端实例变量和一个 priorityComparator 实例变量。我们将使用以下一对方法在此类中实现 add 方法。”
引用的代码是:
public void add (Object o)
{front = add(front,o);}
private static LN add (LN l, Object o)
{
if (l == null || priorityComparator.compare(l.value,o) < 0)
return new LN(value,l);
else {
l.next = add(l.next, o);
return l;
}
}
以上信息和代码的来源在这里->link
很遗憾,我只找到了一个来源:(
QUESTION1:我想知道这种写法对某个集合的实现有什么好处?
所以每个例子,我这样写了我实现的 LinkedList 方法:
//insertion....
public void insert(E data) {
first = insertEnd(first, data);
last = getLast();
//length++;
}
private static <E> Node insert(Node head, E data) {
if (head == null) {
return new Node(data);
} else {
head.setNext(insert(head.getNext(), data));
}
return head;
}
public void printList() {
printList(first);
System.out.println();
}
private static void printList(Node head) {
if (head == null) {
System.out.println("null");
return;
}
System.out.print(head.getData() + "->");
printList(head.getNext());
}
public int size() {
return size(first);
}
private static int size(Node head) {
if (head == null) {
return 0;
} else {
return 1 + size(head.getNext());
}
}
public boolean contains(E data) {
return contains(first, data);
}
public static <E> boolean contains(Node head, E data) {
if (head == null || data == null) {
return false;
}
if (head.getData().equals(data)) {
return true;
}
return contains(head.getNext(), data);
}
//count occurrences of certain value
public int countIf(E t) {
return countIf(first, t);
}
private static <E> int countIf(Node head, E t) {
if (head == null) {
return 0;
}
if (head.getData().equals(t)) {
return 1 + countIf(head.getNext(), t);
}
return countIf(head.getNext(), t);
}
//TODO: WHY IM GETTING HERE AN OVERRIDE REQUEST FROM THE COMPILER??
public ListNode<E> clone() {
first = clone(first);
ListNode<E> copy = new ListNode<>(first);
return copy;
}
private static Node clone(Node head) {
if (head == null) {
return null;
}
Node temp = new Node(head.getData());
temp.setNext(clone(head.getNext()));
return temp;
}
public ListNode<E> invert() {
first = invert(first);
ListNode<E> inverted = new ListNode<>(first);
return inverted;
}
private static Node invert(Node head) {
if (head.getNext() == null) {
return head;
}
Node newHead = invert(head.getNext());
head.getNext().setNext(head);//head.next.next=node;
head.setNext(null);//gead.next=null;
return newHead;
}
问题2我对这个主题的以下原始想法是什么? 所以作为一个初学者,我会尝试分享我对这种方式的潜在好处的看法,如果我弄错了,请尝试纠正我,如果我遗漏了什么,请指出!
- 首先,如果是
assertion、contains()和countIf(),这可能会有所帮助,因为用户不必将列表的头部作为参数。 并且因为每个方法都会像这样调用list1.method(),因此每个列表都会有另一个head node。 - 其次,在
inverting和cloning的情况下,我必须返回ListNode 而不是Node,我可以理解列表的创建必须在invert()或clone()方法中。
很遗憾,我在网上找不到足够的信息,请随时提供您最喜欢的参考资料,并随时撰写您自己的解释。
祝你愉快。 :)
【问题讨论】:
-
如果这是两个问题,那么应该是两个问题。但是您似乎在要求参考/资源,这在 Stack Overflow 上是题外话。如果您想要一个有用的答案,您必须将您的问题缩小到一件事。
标签: java recursion linked-list implementation