Java 反转双链接列表
嘿,我现在被困在我的双链接列表的反向方法上。除了反向方法外,一切都正常(不知怎么的)。我没有收到任何错误-Java 反转双链接列表,java,Java,嘿,我现在被困在我的双链接列表的反向方法上。除了反向方法外,一切都正常(不知怎么的)。我没有收到任何错误-System.out.println(list.reverse())根本没有输出 有什么建议吗?提前非常感谢。:) 好的:我现在已经编辑了我的代码。到目前为止,一切正常。但是,递归方法只是以相同的顺序打印列表,而不是实际反转列表 更新代码: public class DoublyLinkedStringList { private String content; private Doubl
System.out.println(list.reverse())
根本没有输出
有什么建议吗?提前非常感谢。:)
好的:我现在已经编辑了我的代码。到目前为止,一切正常。但是,递归方法只是以相同的顺序打印列表,而不是实际反转列表
更新代码:
public class DoublyLinkedStringList {
private String content;
private DoublyLinkedStringList prev;
private DoublyLinkedStringList next;
public DoublyLinkedStringList(String info) {
content = info;
prev = null;
next = null;
}
private DoublyLinkedStringList(String content, DoublyLinkedStringList prev, DoublyLinkedStringList next) {
this.content = content;
this.prev = prev;
this.next = next;
}
public DoublyLinkedStringList prepend(String info) {
DoublyLinkedStringList newNode = new DoublyLinkedStringList(info);
prev = newNode;
newNode.next = this;
return newNode;
}
public DoublyLinkedStringList delete(int index) {
DoublyLinkedStringList curr = this;
if (index == 0) {
next.prev = null;
return next;
}
for (int i = 0; i < index; i++) {
curr = curr.next;
}
curr.prev.next = curr.next;
if (curr.prev.next != null) {
curr.prev.next.prev = curr.prev;
}
return this;
}
public DoublyLinkedStringList reverse() {
DoublyLinkedStringList currNode = this;
while (currNode != null) {
DoublyLinkedStringList temp = currNode.next;
currNode.next = currNode.prev;
currNode.prev = temp;
if (currNode.prev != null) {
currNode = currNode.prev;
}
}
return this;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (DoublyLinkedStringList currNode = this; currNode != null; currNode = currNode.next) {
sb.append(currNode.content);
if (currNode.next != null) {
sb.append(", ");
}
}
return sb.toString();
}
public static void main(String argv[]) {
DoublyLinkedStringList list = new DoublyLinkedStringList("Testliste");
list = list.prepend("6");
list = list.prepend("5");
list = list.prepend("4");
list = list.prepend("3");
list = list.prepend("2");
list = list.prepend("1");
list = list.prepend("0");
list = list.delete(1);
System.out.println(list);
list = list.reverse();
System.out.println(list);
}
公共类双链接字符串列表{
私有字符串内容;
私有双链接字符串列表prev;
下一步是私有双链接字符串列表;
公共双链接字符串列表(字符串信息){
内容=信息;
prev=null;
next=null;
}
私有双链接字符串列表(字符串内容,双链接字符串列表上一个,双链接字符串列表下一个){
this.content=内容;
this.prev=prev;
this.next=next;
}
公共双链接字符串列表前置(字符串信息){
DoublyLinkedStringList newNode=新的DoublyLinkedStringList(信息);
prev=newNode;
newNode.next=this;
返回newNode;
}
公共双链接字符串列表删除(int索引){
DoublyLinkedStringList curr=this;
如果(索引==0){
next.prev=null;
下一步返回;
}
对于(int i=0;i
}您的设计将遇到的一个问题是,当您反转列表时,头部变成尾部,尾部变成头部。但客户指向的是头部,而不是尾部。即使此操作100%正确,也无法更改客户端的引用。您要做的是将列表的概念作为对象和组成该对象的节点分开(目前您已经将这两个概念组合在一起,因为节点是列表,反之亦然)。通过将它们分开,对列表的引用始终是相同的,无论其中包含什么、顺序等。列表包含头引用和尾引用,节点仅包含下一个/上一个。现在,列表中的每个节点都有head和tail,如果不在head/tail发生变化时(即prepend、delete或reverse)替换每个引用,可能会出现严重的bug。如果将这两个实例移出每个节点,则不必对更改列表进行太多维护。我认为,如果您这样做,那么您将发现实现反向更容易
你的错误正是我要说的问题。在最后你返回这个,那么客户的参考是头部(即这个)。但是,在迭代和反转所有内容之后,头部现在是尾部,因此您通过返回此项返回了新的尾部。尾巴上的toString()也算不了什么。你只需要把头和尾巴都放好就行了。那么它应该会起作用。但请参阅chubbsondubs的答案以进一步改进 因为您有一个双链接字符串列表作为返回类型,所以我认为您需要返回一个新对象。在这种情况下,我建议您在对象上循环,并使用您已经实现的
prepend
方法构建一个新列表(任何情况下都有一些其他错误)。您可以从一个空列表开始,并在扫描原始对象时,在当前元素前面加上前缀
否则,如果要“就地”反转列表,则应返回
void
,用最后一个元素更改头部,并且,由于是双链接的,因此应执行任何其他操作,因为在两个方向上都有指向节点的指针。请尝试以下反转方法:
public class DoublyLinkedList {
Node first, current;
boolean forward;
//constructors... methods...
private Node next() {
if(forward) return current.next();
else return current.previous();
}
public void reverse() {
while(true) {
if(next() == null) {
first = current;
forward = !forward;
return;
}
current = next();
}
}
}
通常我会实现接口
Iteratable
,并使用Iterator
来反转列表,但我的修订版与您当前的模型保持一致。我将节点
的getNext()
和getPrev()
方法的返回类型更改为依赖于forward
变量。现在,列表在“反转”时不会更改链接,但通过变量getNext()
和getPrev()
行为以相反顺序遍历
考虑以下编辑:
class DoublyLinkedStringList {
private Node head, tail;
boolean forward;
/**
* Diese Klasse repraesentiert einen Knoten in der Doubly Linked List der
* Klasse
* <code>DoublyLinkedStringList</code>
*
*/
private class Node {
private String content;
private Node next;
private Node prev;
public Node(String content) { this.content = content; }
public Node(String content, Node next) {
this.content = content;
if(forward) { this.next = next; } //EDITED
else { this.prev = next; } //EDITED
}
public Node getNext() { return (forward) ? next : prev; } //EDITED
public Node getPrev() { return (forward) ? prev : next; } //EDITED
public void setNext(Node next) {
if(forward) { this.next = next; } //EDITED
else { this.prev = next; } //EDITED
}
public void setPrev(Node prev) {
if(forward) { this.prev = prev; } //EDITED
else { this.next = prev; } //EDITED
}
}
public DoublyLinkedStringList() {
this.head = null;
this.tail = null;
}
public Node prepend(String info) {
Node newNode = new Node(info);
newNode.setPrev(null);
newNode.setNext(getHead());
if(newNode.getNext()!=null) {
newNode.getNext().setPrev(newNode); //EDITED
}
if(forward) { head = newNode; } //EDITED
else { tail = newNode; } //EDITED
if(getTail() == null) { //EDITED
if(forward) { tail = newNode; } //EDITED
else { head = newNode; } //EDITED
}
return head;
}
public Node delete(int index) {
Node currNode = getHead();
int count = 0;
if (index == 0) {
if(forward) { head = head.next; } //EDITED
else { tail = tail.prev; } //EDITED
return head;
}
while (currNode != null) {
if (count + 1 == index) {
currNode.next.prev = currNode.prev;
currNode.prev.next = currNode.next; //EDITED
break;
}
currNode = currNode.getNext(); //EDITED
count++;
}
return currNode;
}
private Node next() {
Node currNode = head;
if (forward) {
return currNode.getNext();
} else {
return currNode.getPrev();
}
}
public Node getHead() { return (forward) ? head : tail; } //EDITED
public Node getTail() { return (forward) ? tail : head; } //EDITED
public DoublyLinkedStringList reverse() { forward = !forward; return this; }
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
//EDITED LOOP STRUCTURE
for (Node currNode = getHead(); currNode != null; currNode = currNode.getNext()) {
sb.append(currNode.content);
if (currNode.getNext() != null) {
sb.append(", ");
}
}
return sb.toString();
}
public static void main(String argv[]) {
DoublyLinkedStringList list = new DoublyLinkedStringList();
list.prepend("6");
list.prepend("5");
list.prepend("4");
list.prepend("3");
list.prepend("2");
list.prepend("1");
list.prepend("0");
list.delete(3);
System.out.println(list);
System.out.println(list.reverse());
}
}
这就是我的解决方案。不幸的是,我没有更多的时间作解释性说明
public class DoublyLinkedStringList {
private String info;
private DoublyLinkedStringList prev;
private DoublyLinkedStringList next;
public DoublyLinkedStringList(String pInfo)
{
info = pInfo;
prev = null;
next = null;
}
private DoublyLinkedStringList(String pInfo, DoublyLinkedStringList pPrev, DoublyLinkedStringList pNext)
{
info = pInfo;
prev = pPrev;
next = pNext;
}
public DoublyLinkedStringList prepend(String info)
{
DoublyLinkedStringList n = new DoublyLinkedStringList(info);
prev = n;
n.next = this;
return n;
}
public DoublyLinkedStringList delete(int index)
{
if (index == 0)
{
next.prev = null;
return next;
}
DoublyLinkedStringList d = this;
for (int i = 0; i<index; i++)
d = d.next;
// d is now the node which should be deleted
// after delete(x) "next" schould be on pos x
d.prev.next = d.next; // take the next of the prev and set the new next to the next of d
if (d.prev.next != null) // if the next of d was not set to null, it must get to know his new prev (d's prev)
d.prev.next.prev = d.prev;
return this;
}
public DoublyLinkedStringList reverse() // moe or less less similar to my implementation in IntList.java
{
DoublyLinkedStringList oldLast = getLast();
next.reverse(this);
prev = next;
next = null;
return oldLast;
}
public void reverse(DoublyLinkedStringList last)
{
if (next != null)
next.reverse(this);
prev = next;
next = last;
}
public DoublyLinkedStringList getLast()
{
if (next == null)
return this;
return next.getLast();
}
@Override
public String toString()
{
String r = "";
for (DoublyLinkedStringList i = this; i != null; i = i.next)
{
r += i.info;
if (i.next != null)
r += ", ";
}
return r;
}
public String reverseToString() // uses prev; just for testing issues :)
{
String r = "";
for (DoublyLinkedStringList i = getLast(); i != null; i = i.prev)
{
r += i.info;
if (i.prev != null)
r += ", ";
}
return r;
}
public static void main(String argv[])
{
DoublyLinkedStringList list = new DoublyLinkedStringList("Test");
list = list.prepend("6");
list = list.prepend("5");
list = list.prepend("4");
list = list.prepend("3");
list = list.prepend("2");
list = list.prepend("1");
list = list.prepend("0");
list = list.delete(1);
System.out.println(list);
System.out.println(list.reverseToString()+"\n");
list = list.reverse();
System.out.println(list);
System.out.println(list.reverseToString());
list = list.delete(6);
list = list.delete(0);
System.out.println(list);
list = list.reverse();
list = list.prepend("1");
System.out.println(list);
}
公共类双链接字符串列表{
私有字符串信息;
私有双链接字符串列表prev;
下一步是私有双链接字符串列表;
公共双链接字符串列表(字符串pInfo)
{
info=pInfo;
prev=null;
next=null;
}
专用双链接字符串列表(字符串pInfo、双链接字符串列表pPrev、双链接字符串列表pNext)
{
info=pInfo;
prev=pPrev;
next=pNext;
}
公共双链接字符串列表前置(字符串信息)
{
杜布里