我有这个代码,它应该将SortedLinkedList
的两个实例合并到一个SLL中(基于mergeSort合并),但是返回一个空列表:
import java.util.LinkedList;
public class SortedLinkedList<T extends Comparable<? super T>>
extends LinkedList<T> {
private LinkedList<T> list; // the sorted list
// constructor, sorted with insertion sort
public SortedLinkedList(LinkedList<T> in)
{
if(in.peek() == null || in.size() == 1)
return;
else {
list = new LinkedList<T>();
for(T e : in)
list.add(e);
int i, j;
T temp;
for(i = 0; i < list.size(); i++){
j = i;
temp = list.get(j);
while(j > 0 && list.get(j-1).compareTo(temp) > 0){
list.set(j, list.get(j-1));
j--;
}
list.set(j, temp);
}
}
}
// return the union of the sorted linked lists this
// and other
public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
list = new LinkedList<T>();
SortedLinkedList<T> temp = new SortedLinkedList<T>(list);
int i = 0, j = 0;
while(i < this.size() && j < other.size()){
if(this.get(i).compareTo(other.get(j)) <= 0){
temp.add(this.get(i));
i++;
}
else {
temp.add(other.get(j));
j++;
}
}
while(i < this.size()){
temp.add(this.get(i));
i++;
}
while(j < other.size()){
temp.add(other.get(j));
j++;
}
return temp;
}
// print the items in list
public void print()
{
for(T e : list)
System.out.println(e);
}
}
在SLL构造函数中,我只需返回null
列表(并且私有变量list在此方法的第一行中初始化)。但是据我所知,这仍然应该给我一个SLL对象(最初也是null
)。我可以在方法本身中添加temp,但在打印列表时得到NullPointerException
。
我意识到使用get LinkedList
效率不高。我解决了这个问题后,我会用迭代器切换它们。
任何提示都会非常感激。
编辑:有趣的是,如果我将两个列表放在一个临时LL中,然后在其上使用构造函数,我会得到相同的结果。由于SLL扩展了LL:
,因此类型是兼容的public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
LinkedList<T> temp = new LinkedList<T>();
temp.addAll(this);
temp.addAll(other);
SortedLinkedList<T> merge = new SortedLinkedList(temp);
return merge;
}
EDIT2:似乎@Mead是正确的...虽然size()和get()似乎适用于SLL,但add()却没有。我在想,因为我正在扩展LinkedList,所以它也适用于SLL。它没有,并且压倒它们也没有做任何事情......我对此没有想法。建议?
答案 0 :(得分:0)
答案 1 :(得分:0)
大!您的编辑几乎可以揭示您的问题:您没有正确扩展LinkedList。解决这个问题,然后继续工作。
手头的问题:这是一个名为SortedLinkedList
的类。我们可以假设它就像LinkedList一样,但它中的值是排序的。所以,鉴于此,这应该有效:
LinkedList<Integer> unsorted = new LinkedList<Integer>();
unsorted.add(200);
unsorted.add(100);
unsorted.add(300);
SortedLinkedList<Integer> sorted = new SortedLinkedList<Integer>(unsorted);
System.out.println(sorted.size());
for (Integer i : sorted) {
System.out.println(i);
}
// Should print out:
// 3
// 100
// 200
// 300
但它不会。运行你的代码,它打印出什么?
返回?为什么打印出来?首先,考虑可以在类的代码中使用的两个变量:this
引用SortedLinkedList对象,this.list
引用SortedLinkedList对象内的实例变量。然后让我们看一下构造函数:当你添加到列表中时,你正在调用this.list.add()
。你所写的内容使得SortedLinkedList成为list
实例变量的包装器 - 你不会添加到你要添加到其中的列表(this
)的SortedLinkedList(this.list
)。
使用this.list
实例变量的唯一方法是构造函数,print和makeUnion。所有其他LinkedList方法都不知道list
变量,所以当我调用get()时:
LinkedList<Integer> unsorted = new LinkedList<Integer>();
unsorted.add(200);
unsorted.add(100);
unsorted.add(300);
SortedLinkedList<Integer> sorted = new SortedLinked<Integer>(unsorted);
System.out.println(sorted.get(0));
它不知道要查看您的this.list
变量,因此它不会打印100。实际上,它会崩溃,因为索引0中没有值。您没有添加到get()实际使用的实例变量,因此方法认为SortedLinkedList对象为空。 this.list
是继承方法不知道的新变量。
因此,如果我们检查您的最新编辑:
public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
LinkedList<T> temp = new LinkedList<T>();
temp.addAll(this);
temp.addAll(other);
SortedLinkedList<T> merge = new SortedLinkedList(temp);
return merge;
}
temp.addAll(this)
不起作用,因为this
的所有方法都认为该列表为空,因为它们没有查看this.list
。出于同样的原因,temp.addAll(other)
也不起作用。
扩展类时常见的是您希望现有方法继续工作。这意味着您需要将数据存储在get()和其他方法所期望的位置。你是怎样做的?好吧,你已经在做了! 您已经做了正确的事 - 但您是在实例变量this.list
而不是this
上进行的。开始调用this.add()
,this.set()
,this.size()
而不是this.list.add()
并完全删除实例变量list
- 不需要它,您有this
。然后数据将是其他方法所期望的数据。
(并在构造函数的第一行调用super(),因此调用超类构造函数中的代码)。祝你的作业好运 - 我建议在添加新方法之前按原样测试对象。</ p>