回到我的基本ADT东西来修改面试,并试图通过学习Java来一举两得。尝试使用通用链接列表(我自己创建)编写合并排序的简单算法。事实证明,这比我想象的要困难得多!有人可以帮帮我吗?我将开始研究基础知识,并将在我进一步了解时更新这篇文章。
我的通用链表代码如下:
public class NodeList<T extends Comparable<T> > {
private T head;
public NodeList<T> tail;
public NodeList( T item, NodeList<T> list ) {
head = item;
tail = list;
}
}
我正在尝试在我创建的另一个类中访问此类,如下所示:
public class MyList<T extends Comparable<T>> {
private NodeList<T> nodes;
private static int size;
public MyList( ) {
nodes = null;
}
public MyList(T[] array ){
for( T item : array ) {
nodes = new NodeList<T>(item, nodes);
}
size = array.length;
}
public void add( T item ) {
nodes = new NodeList<T>( item, nodes );
size++;
}
public void addEnd( T item ) {
NodeList<T> temp = nodes;
while ( temp == null || temp.tail != null) {
temp = temp.tail;
}
size++;
temp.tail = new NodeList<T> ( item, null);
}
到目前为止,我相信一切都要正确,直到add和addEnd方法,它们应该分别在列表的开头和列表的末尾添加泛型。
我的代码继续:
public static <S extends Comparable<S>>
MyList<S> sort( MyList<S> list ) {
if ( size > 1 ) {
MyList<S> left = leftHalf( list );
MyList<S> right = rightHalf( list );
list = merge( left, right );
}
return list;
}
private static <S extends Comparable<S>>
MyList<S> merge( MyList<S> left, MyList<S> right ) {
}
private static <S extends Comparable<S>>
MyList<S> leftHalf( MyList<S> list ) {
MyList <S> leftSide = new MyList();
int middle;
if(size % 2 == 1) {
middle = size +1;
} else {
middle = size;
}
for ( int countToMiddle = 0; countToMiddle < middle ; countToMiddle++ ) {
leftSide.addEnd(nodes);
}
// return elements from 0 .. list.size() / 2
}
我收到错误:
MyList中的addEnd(S)无法应用于(NodeList)
在我运行
时发生leftSide.addEnd(节点);
任何人都可以看到这个原因/告诉我,如果我的工作到目前为止是正确的吗?非常感谢!
答案 0 :(得分:2)
如果您希望NodeList和MyList仅包含Comparable
项,
您可以用以下内容替换泛型参数T
:
public class NodeList<T extends Comparable> {
或者
public class NodeList<T extends Comparable<T>> {
并将Comparable
替换为T
。这样,你知道T至少实现了Comparable的方法。
Oracle的tutorials for generics应该可以帮助您掌握它们。
您可能遇到的一个问题是您从静态函数中引用成员变量,例如您leftHalf
中的成员变量:
for ( int countToMiddle = 0; countToMiddle < middle ; countToMiddle++ ) {
leftSide.addEnd(nodes);
}
nodes
是一个成员变量,即一个非静态变量,因此您无法从静态方法中调用它。对于该示例,您必须从传递的MyList
:
for ( int countToMiddle = 0; countToMiddle < middle ; countToMiddle++ ) {
leftSide.addEnd(list.nodes);
}
对于尝试使用成员变量的其他静态方法也是如此。
此外,您收到错误的原因如下:addEnd(S) in MyList<S> cannot be applied to (NodeList<T>)
是因为S
根据您的类型参数而定,是可比较的。 NodeList
不会扩展可比较的内容!
你有两个解决方案
MyList.addEnd
或者提出一种更符合您课程需要的不同解决方案。
虽然我意识到你正在实施一个链接列表,只是为了提高你的面试技巧(祝你好运!),我只想补充一点,已经有一个已经可用的LinkedList已经可用于Java。 / p>
答案 1 :(得分:1)
为什么两次发布几乎相同的问题? 您可以扩展您的问题,添加评论等。
我们已经给了你hint。 :)
答案 2 :(得分:0)
发生错误是因为类NodeList没有接收泛型T类和NodeList的构造函数。 实际上,此实现将替换节点在每个循环中引用的引用对象。你也应该解决这个问题。
你应该做的是将T作为一个Comparable本身,并更改属性,如:
public class NodeList<T extends Comparable> {
private T head;
private NodeList tail;
public NodeList( T item, NodeList list ) {
head = item;
tail = list;
}
}
如果你告诉我们代码的确切含义会更好。