是的,这是我的家庭作业项目之一 - 实施基于单链表的循环链表。它非常简单,代码易于阅读。我的所有属性都是公开的,以避免 getters 和 setters 以及私有企业。出于本项目的目的, public 就足够了。
我初始化了我的 nItems 计数器(列表中的项目数)和属性字段中的链接头,但我稍后会通过在构造函数中初始化它来更改它。
我的 step()方法似乎根本不起作用。我的编译器只是冻结片刻,然后什么都没有显示出来。如果我调用它4次,这就是step()方法应该如何工作:
List: 40 80 30 20 10 70 50
List: 80 30 20 10 70 50 40
List: 30 20 10 70 50 40 80
List: 20 10 70 50 40 80 30
Find()方法正常,只要我们搜索的值在链接列表中。如果不是,它将永远继续下去。如果这是我的列表,那么如果您搜索不存在的值(我逐步调试它), find()方法会发生什么:
70 60 50 40 30 20 10 10 10 10 10 10 10 10...and 10 forever
原因:如果我们正在搜索的键值不存在,它将永远不会从while循环中退出,因此永远重复 current = current.next
while(current.dData != key) {
current = current.next;
我的删除方法说它按照我的意愿删除了值60,但这就是我得到的:
Deleted link with key 60
70 60 40 30 20 10 // lie! it deletes 50 instead of 60
请同时查看我的display()和insert()方法。它们看起来很好,但我可能是错的,它可能是我使用find()和delete()方法遇到的所有问题的根源。
提前非常感谢!!!
class Link {
public int dData;
public Link next;
public Link(int dd) {
dData = dd;
}
public void displayLink() {
System.out.print(dData + " ");
}
}
class CircList {
public Link head = null;
int nItems = 0;
public boolean isEmpty() {
return (nItems == 0);
}
// INSERT
public void insert(int key) {
Link current = new Link(key);
if(isEmpty())
head = current;
current.next = head;
head = current;
nItems++;
}
// STEP
public void step() {
Link current = head;
do {
current = current.next;
} while(current != head);
}
// FIND
public Link find (int key) {
Link current = head;
while(current.dData != key) {
current = current.next;
}
return current;
}
// DELETE
public Link delete(int key) {
Link current = head;
while(current.dData != key) {
current = current.next;
}
if(current == head)
head = head.next;
else {
current.next = current.next.next;
nItems--;
}
return current;
}
// DISPLAY
public void displayList() {
Link current = head; // start at beginning
int counter = nItems;
while(true) {
if(counter != 0) {
current.displayLink();
current = current.next; // move to next link
counter--;
}
else
break;
}
}
}
class CircListApp {
public static void main(String[] args) {
Link f, d;
CircList theList = new CircList();
theList.insert(10); // insert items
theList.insert(20);
theList.insert(30);
theList.insert(40);
theList.insert(50);
theList.insert(60);
theList.insert(70);
//System.out.println(theList.nItems + " ");
theList.displayList(); // display list
System.out.println("");
f = theList.find(30); // find item
if( f != null)
System.out.println("Found link with key " + f.dData);
else
System.out.println("Can't find link with key 30");
// theList.step();
//
// System.out.println("Inserting link with key 80");
// theList.insert(80);
// theList.displayList(); // display list
//
d = theList.delete(60); // delete item
if( d != null )
System.out.println("Deleted link with key " + d.dData);
else
System.out.println("Can't delete link with key 60");
theList.displayList(); // display list
//
// f = theList.find(99); // find item
// if( f != null)
// System.out.println("Found link with key " + f.dData);
// else
// System.out.println("Can't find link with key 99" );
// theList.displayList(); // display list
//
// d = theList.delete(13); // delete item
// if( d != null )
// System.out.println("Deleted link with key " + d.dData);
// else
// System.out.println("Can't delete link with key 13");
// theList.displayList(); // display list
//
// System.out.println("Stepping through list");
// for(int j=0; j<theList.getSize; j++)
// {
// theList.step();
// theList.displayList();
// }
//
// System.out.println("Will delete and step one by one");
// while(theList.isEmpty() == false)
// {
// theList.delete();
// theList.step();
// theList.displayList();
// }
} // end main()
}
答案 0 :(得分:1)
到你的“步骤”方法: 您创建一个名为current的本地引用,该引用最初指向head。之后
current = current.next
它引用了头部的继承者。在下一步中,它引用了它的后继者,依此类推。但它是本地参考,因此您不需要更改列表中的任何内容。
我从你想要的输出中推断出你需要做的事情就像
一样简单if( head != null && head.next != null )
head = head.next
下一个:对于你的find-method: 好吧,从您的循环条件来看,很明显,如果密钥不在列表中,它将永远运行,因为这是您唯一的破坏条件。您应该考虑一种机制,在您查看列表中的每个项目后使其停止。提示:看看你在step()方法版本中做了些什么。
到你的删除方法: 第一部分(部分)没问题(它与find-method具有相同的无限循环问题)。 你要做的是遍历列表,直到当前数据等于密钥。没关系。
但是现在,current是对要删除的元素的引用。但你要做的是将current.next设置为current.next.next,这意味着你要删除当前的后继,而不是当前本身!在您搜索密钥的循环中,您必须跟踪前一个,以便您可以将predecessor.next更改为current.next,这是您真正想要做的。
然后,当然,您必须检查它是否是您正在删除的头部,如果是这种情况,您必须将其设置为前一个或后一个。
最后,我看到你的insert()方法有问题!我没有看到它如何产生循环链表,因为你让新插入的元素指向头部并使其成为新的头部,但没有任何东西指向它。那么你只创建一个单链表?你在头部之前插入一个新项目(current.next = head),但是你现在也应该让头部的前任指向新项目,当前!