【问题标题】:Creating a stack from a circular linked list in order to print the list reversely [closed]从循环链表创建堆栈以反向打印列表[关闭]
【发布时间】:2013-05-11 08:30:52
【问题描述】:

我正在为我的测试解决一些练习问题。我教科书中的问题要求我将循环链表中的内容反向打印。所以我的想法是创建一个堆栈,将内容移动到堆栈然后弹出它。

这是我所做的:

    public void reversePrint() {
   Stack stack = new Stack();

   Node<E> temp = list;
   do {
   stack.push(temp);
   temp = temp.getNext();
   } while (temp != list);

   while (!stack.empty()) {
   System.out.print(stack.pop());
   }
   }

循环列表.java

    public class CircularList<E> implements List<E> {

  Node<E> list;
  int size;

  public CircularList() {
    list = new Node(null);
    list.setNext(list);
    size = 0;
  }

  @Override
  public void add(E element) {
    Node<E> newNode = new Node(element);
    newNode.setNext(list.getNext());
    list.setNext(newNode);
    size++;
  }

  @Override
  public boolean remove(E element) {
    Node<E> location = find(element);
    if (location != null) {
      location.setNext(location.getNext().getNext());
      size--;
    }
    return location != null;
  }

  @Override
  public E get(E element) {
    Node<E> location = find(element);
    if (location != null) {
      return (E) location.getNext().getInfo();
    }
    return null;
  }

  @Override
  public boolean contains(E element) {
    return find(element) != null;
  }

  @Override
  public int size() {
    return size;
  }

  @Override
  public Iterator<E> iterator() {
    return new Iterator<E>() {
      Node<E> tmp = list.getNext();

      @Override
      public boolean hasNext() {
        return tmp != list;
      }

      @Override
      public E next() {
        E info = tmp.getInfo();
        tmp = tmp.getNext();
        return info;
      }

      @Override
      public void remove() {
        throw new UnsupportedOperationException("Not supported yet.");
      }
    };
  }

  protected Node<E> find(E element) {
    Node<E> tmp = list;
    while (tmp.getNext() != list && !tmp.getNext().getInfo().equals(element)) {
      tmp = tmp.getNext();
    }

    if (tmp.getNext() == list) {
      return null;
    } else {
      return tmp;
    }

}

Node.java

public class Node<E> {

  E info;
  Node<E> next;

  public Node(E element) {
    info = element;
    next = null;
  }

  public void setInfo(E element) {
    info = element;
  }

  public E getInfo() {
    return info;
  }

  public void setNext(Node<E> next) {
    this.next = next;
  }

  public Node<E> getNext() {
    return next;
  }
}

我的问题是我不能使用 do。我需要一个不同的解决方案。有什么帮助吗?

【问题讨论】:

  • 为什么不能使用do
  • 您需要以某种方式遍历列表的节点...如果不是do,那么您允许/需要使用什么?顺便说一句...Node 中有 getPrevious() 方法吗?
  • @A4L 不,它是一个单循环链表,但我设计了一个迭代器,仅使用 next 和 hasNext 方法。
  • @JonSkeet 在我练习的课程中还没有参加。
  • @user2272227: do 是一个循环 - 但由于某种原因你不能使用它。 break 是循环的一部分,但你不能使用它。所以你的评论并没有说明你可以使用什么。

标签: java linked-list stack


【解决方案1】:

我假设您自己编写了 LinkedList(使用 Node&lt;T&gt; 类)。

如果列表是双向链接的:

从列表中的最后一个元素开始(如果您不存储对尾部的引用,则迭代节点直到到达最后一个元素)并使用getPrevious() 遍历列表(无论getNext() 的相反名称是什么)。

如果列表是单链接的:

您可以递归遍历列表并在展开时打印元素,而不是使用堆栈。

public static void <T> reverse(Node<T> current, Node<T> stopAt) {
   Node<T> next = current.getNext();
   if (next != stopAt) {
      reverse(next);
   }
   System.out.println(next.getValue(), stopAt);
}

这很简单,但效率不高。如果列表包含太多元素,您甚至可能会遇到递归深度过深的问题。

*edit : 固定终止条件

【讨论】:

  • 对于方法,我不能使用参数。我只需调用 printReverse() ,它就会反向打印列表中的所有内容。循环链表 fyi
  • 编辑了主帖。我的整个代码现在已经发布了。
  • 您可以将此递归版本用作CircularList 类中的私有方法。在您的 printReverse() 方法中,您调用它并将列表的当前头部作为参数传递。但是因为你不允许使用 do {} 而我怀疑你不会被允许使用递归。坚持@Jon Skeet 的建议(:
【解决方案2】:

如果您“被允许”使用while 循环,您只需将do 循环转换为该循环,使用break 即可退出:

while (true) {
    stack.push(temp);
    temp = temp.getNext();
    // If we're back to the beginning, we're done
    if (temp == list) {
        break;
    }
}

或者如果你可以使用size,那就更简单了:

Node<E> temp = list;
for (int i = 0; i < size; i++) {
    stack.push(temp);
    temp = temp.getNext();
}

【讨论】:

  • 乔恩,是的!但是我们还没有休息,除了休息还有其他方法吗?
  • @user2272227:好吧,我现在给了你一个for 循环,但也许你也不允许使用它......你让我们猜测你被允许使用,这使得 IMO 成为一个毫无意义的问题。
  • @user2272227:好的,我回答的第二部分应该没问题吧?
  • 是的,但第二部分只是添加所有内容并打印出来?我希望它反向打印列表?它不在这里检查任何东西?
  • @darrenmc:是什么让你这么说?我在这个问题中看不到任何暗示。我同意递归是另一种选择,但 OP 已经有一个计划,可以在没有递归的情况下工作。
猜你喜欢
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-08
  • 1970-01-01
相关资源
最近更新 更多