我正在努力使我的双向链表使用尾递归。
public class DoublyLinkedList
{
private int noOfItems;
private DLLNode head;
private DLLNode tail;
// Default constructor
public DoublyLinkedList()
{
head = null;
tail = null;
this.noOfItems = 0;
}
public void AddItem(String value)
{
DLLNode newNode = new DLLNode(value);
if (head == null)
{
head = newNode;
noOfItems++;
}
else {
DLLNode current = head;
while(current != null) {
if (current.GetNextNode() == null) {
current.setNextNode(newNode);
newNode.setPrevious(newNode);
noOfItems++;
break;
}
current = current.GetNextNode();
}
}
}
}
我的Node类如下:
public class DLLNode
{
private DLLNode previous;
public DLLNode next;
private String value;
public DLLNode(String value)
{
this.value = value;
}
/* This method returns the String item of data held in this node */
public String GetDataItem()
{
return value;
}
public void setDataItem()
{
this.value = value;
}
/* This method returns the node immediately prior to this node in the list or
* null if there is no such node */
public DLLNode GetPreviousNode()
{
return previous;
}
public void setPrevious(DLLNode previous)
{
this.previous = previous;
}
/* This method returns the node immediately after this node in the list or null
* if there is no such node. */
public DLLNode GetNextNode()
{
return next;
}
public void setNextNode(DLLNode next)
{
this.next = next;
}
public void AddItem(String value)
{
if (next == null)
{
next = new DLLNode(value);
}
else
next.AddItem(value);
}
}
这是我添加项目的代码。我还尝试使用尾递归,这是下面显示的代码:
public void AddItem(String value)
{
if (head == null)
{
head = new DLLNode(value);
noOfItems++;
}
else {
head.AddItem(value);
}
}
我写的递归版本有效。然而,它并没有双重联系。
我理解,要成为一个双向链表,节点需要知道接下来会发生什么以及接下来会发生什么。所以在我的Add Item中,我需要一些东西让下一个节点知道它之前发生了什么吗?如果有任何关于如何做的建议?
先谢谢。
答案 0 :(得分:1)
使用我自己的假设Node
课程 - 您可以根据自己的DLLNode
进行调整:
void addItem(Node head, Node item) {
if(node.next == null) {
// Stopping condition
node.next = item;
item.previous = node;
} else {
// Recurse
addItem(node.next, item);
}
}
或者,多一点OO,假设此代码是Node
的一部分,只需将head
替换为this
,您需要更少的方法参数:
void addItem(Node item) {
if(this.next == null) {
// Stopping condition
this.next = item;
item.previous = this;
} else {
// Recurse
this.next.addItem(item);
}
}
或者,如果您不想传递Node
,而是创建一个:
public void addItem(String value) {
if(this.next == null) {
// Stopping condition
Node newNode = new Node(value, this, null);
this.next = newNode;
} else {
// Recurse
this.next.addItem(value);
}
}
这假设一个构造函数:
public Node(String value, Node previous, Node next) {
this.value = value;
this.previous = previous;
this.next = next;
}
我认为这显示了整洁的基础知识。您可以使用getter / setter等来改进它。
我已经为你提供了Node
的方法,但是你有一个包含它的DoublyLinkedList
类。对于列表类来说,在节点上的方法是一个非常薄的包装器是很常见的:
public class DoublyLinkedList {
private Node head;
public addItem(String value) {
head.addItem(value);
}
}
(你需要处理head
为空的情况。为了简洁,我把它留了出来)
请注意,在Java中,这种递归解决方案并不理想,因为该语言不会优化尾递归,而对于长列表,您将获得堆栈溢出。迭代解决方案不会消耗堆栈。