我需要为链表Queue实现一个toString()递归方法。我知道我的toString方法在我上周做的链表实现上工作得很好,所以我在处理它的Queue方面有些不对劲。
我的QueueList的toString方法:
public String toString()
{
if (front.info == null)
{
System.out.println("Error, queue is empty");
return "";
}
if (front.link == null) //base case: if this is last element in stack
{
return (" \"" + front.info + "\" , ");
}
else //normal recursive function
{
return (" \"" + front.info + "\" , " + front.link.toString());
}
}
和我的构造函数等QueueList:
public class QueueNode
{
E info;
QueueNode link;
}
private QueueNode front;//first element to be placed into queue
private QueueNode rear;//last element to be placed into queue
private int NoE;//counter for number of elements in queue
public QueueList()
{
front = null;
rear = null;
NoE = 0;
}
我尝试使用此测试查看其中发生了什么:
public boolean test() {
QueueList<String> q = new QueueList<String>();
q.enqueue("The Godfather");
q.enqueue("Casino");
q.enqueue("Goodfellas");
String r = q.toString();
q.PrettyPrint();
输出
IN -> [ "The Godfather" , QueueList$QueueNode@a3901c6] -> OUT.
我意识到这是因为我在front.link.toString()
方法的递归部分说toString
,但即使我将其更改为front.link.info.toString()
,我的输出也是
IN -> [ "The Godfather" , Casino] -> OUT.
这可能与我的入队和出队方法有关,具体如下:
public void enqueue(E element)
{
QueueNode newNode = new QueueNode();//creates new Node to hold element
newNode.info = element;//set info of new Node to element
newNode.link = null;//make link null since it's at back of list
if (rear == null)//checks if queue is empty
{
front = newNode;
}
else
{
rear.link = newNode;//sets second to last node's link to newNode
}
rear = newNode;//makes newNode the new last link
NoE++;//increase counter
}
public E dequeue() throws InvalidOperationException
{
if (front == null)//sanitize code
{
throw new InvalidOperationException("There is nothing in the queue.");
}
E element = front.info;//creates an element file that takes the info in front of queue
front = front.link;//makes second-to-front element new front
if (front == null)//if this emptied the queue, make sure rear is also empty
{
rear = null;
}
NoE--;//reduce counter
return element;
}
如果可以,请帮帮我。感谢。
答案 0 :(得分:0)
绝对不需要递归toString
,实际上不正确这样做。您的数据结构不是递归的(即树),而是线性的。
如果你的列表中包含了100万个项目,那么你很快就会耗尽堆栈空间(StackOverflow,字面意思)。
改为使用循环。
编辑:如果您必需以递归方式执行此操作,那么问题是递归方法必须是QueueNode#toStringRecursive()
,而不是Queue#toString()
。方法Queue#toString()
分配缓冲区并将其提供给toStringRecursive()
上执行递归的特殊QueueNode
方法。 QueueNode#toString()
必须仅对其自己的节点内容负责。
方法Queue#toString()
public String toString()
{
StringBuilder buf = new StringBuilder();
if (front == null)
// queue is empty
else
front.toStringRecursive(buf);
return buf.toString();
}
方法QueueNode#toStringRecursive()
public void toStringRecursive(StringBuilder buf)
{
buf.append(this.toString());
if (this.link != null)
this.toStringRecursive(buf);
}
其中QueueNode.toString()
仅负责对一个节点(本身)进行字符串化。
请注意,这是一种方式。可以在Queue
上将其写为递归方法,但不能将其称为toString()
。 Queue#toString()
将设置初始条件,然后调用递归。