简体   繁体   English

使用尾递归的DoublyLinkedList-InsertItem

[英]DoublyLinkedList using tail recursion - InsertItem

I'm currently trying to create a DoublyLinked list that uses tail recursion. 我当前正在尝试创建使用尾递归的DoublyLinked列表。

I have my addItem fully working. 我的addItem可以正常工作了。 My InsertItem successfully inserts and item at the specified index. 我的InsertItem成功插入和项在指定的索引处。 However it removes whatever item was there and doesn't move all the data along. 但是,它将删除那里的所有项目,并且不会移动所有数据。 My code also crashes when trying to add at index 1. I have commented out the code I attempted to get this working. 尝试添加索引1时,我的代码也会崩溃。我已注释掉尝试使该代码正常工作的代码。

Here is my Node class: 这是我的Node类:

public class DLLNode
{
    private DLLNode previous;
    public DLLNode next;
    private String value;

    public DLLNode(String value)
    {
        this.value = value;
        this.previous = previous;
        this.next = next;
    }

    public DLLNode(String value, DLLNode next, DLLNode previous)
    {
        this.value = value;
        this.next = next;
        this.previous = previous;
    }

  public String GetDataItem()
  {
    return value;
  }

  public void setDataItem()
  {
      this.value = value;
  }

  public DLLNode GetPreviousNode()
  {
    return previous;
  }

  public void setPrevious(DLLNode previous)
  {
      this.previous = previous;
  }

  public DLLNode GetNextNode()
  {
    return next;
  }

  public void setNextNode(DLLNode next)
  {
      this.next = next;
  }

  public void addItem(String value) {
     if(this.next == null) {
          DLLNode newNode = new DLLNode(value);
          this.next = newNode;
     } else {
          this.next.addItem(value);
     }
}


  public void InsertItemHelper(String value, int indexToInsert, int current, DLLNode currNode)
  {
      /*if (indexToInsert == 1)
      {
          DLLNode newNode = new DLLNode(value);
          currNode.setNextNode(newNode);
      }*/
      if (current == indexToInsert-2)
      {
          DLLNode newNode = new DLLNode(value); 
          currNode.setNextNode(currNode.GetNextNode().GetNextNode());
          newNode.setNextNode(currNode.GetNextNode());
          currNode.setNextNode(newNode);
          newNode.setPrevious(currNode);   
      }
      else
      {
          InsertItemHelper(value, indexToInsert, current+1, currNode.GetNextNode());
      }
  }

    public void DeleteItemHelper(int indexToDelete, int current, DLLNode currNode)
  {
      if (current == indexToDelete-2)
      {
          currNode.setNextNode(currNode.GetNextNode().GetNextNode());
      }
      else
      {
          DeleteItemHelper(indexToDelete, current+1, currNode.GetNextNode());
      }
  }



}

And here is my DoublyLinkedList class. 这是我的DoublyLinkedList类。 Any help and tips much appreciated. 非常感谢任何帮助和技巧。

public class DoublyLinkedList
{
    private int noOfItems;
    private DLLNode head;
    private DLLNode tail;
  // Default constructor
  public DoublyLinkedList()
  {
     head = null;
     tail = null;
     this.noOfItems = 0;

  }


  public int GetNoOfItems()
  {
    return noOfItems;
  }

  /* Returns the String value held at index (base zero) or null if the index
   * is out of bounds */
  public String GetItemByIndex(int index)
  {
    return null;
  }


  public DLLNode GetNodeByIndex(int index)
  {
    return null;
  }


  public void AddItem(String value)
  {
      if (head == null)
      {
          DLLNode newNode = new DLLNode(value);
          head = newNode;
          noOfItems++;
      }
      else
      {
      head.addItem(value);
      noOfItems++;
      }
       }



  public void InsertItem(int index, String value)
  {
      if (index > noOfItems)
      {
          AddItem(value);
      }
      else {
        head.InsertItemHelper(value, index, 0, head); 
        noOfItems++;
      }


  }


  public void DeleteItem(int index)
  {

          if (index ==0)
          {
              System.out.println("Out of Bounds");
          }
          if (index > noOfItems)
          {
             System.out.println("Out of Bounds");
          }
          if (head == null)
          {
              System.out.println("No Item to remove");
          }
          else if (index == 1)
          {
              head = head.GetNextNode();
              noOfItems--;
          }
          else
          {
              head.DeleteItemHelper(index, 0, head);
              noOfItems--;
          }

  }

  public int getNoOfItems()
  {
      return this.noOfItems;
  }

  public boolean isEmpty()
  {
      return (head == null);
  }


}

Think about what's going on here: 考虑一下这里发生了什么:

currNode.setNextNode(currNode.GetNextNode().GetNextNode());
newNode.setNextNode(currNode.GetNextNode());
currNode.setNextNode(newNode);
newNode.setPrevious(currNode);

Analysis of your snippet 您的摘要分析

let A:= currnode; B:=currnode.getNextNode(); C:=currnode.getNextNode(); A:= currnode; B:=currnode.getNextNode(); C:=currnode.getNextNode(); A:= currnode; B:=currnode.getNextNode(); C:=currnode.getNextNode();

So we have something like A -> B -> C 所以我们有类似A-> B-> C

currNode.setNextNode(currNode.GetNextNode().GetNextNode());

A ->C A-> C

newNode.setNextNode(currNode.GetNextNode());

newNode -> C newNode-> C

currNode.setNextNode(newNode);

A -> newNode -> C A-> newNode-> C

newNode.setPrevious(currNode);

set backlink from newNode to A 设置从newNode到A的反向链接


What you probably want to do 您可能想做什么

newNode.setNextNode(currNode.getNextNode());

newNode -> B newNode-> B

now we can change the link from currNode to the newNode 现在我们可以将链接从currNode更改为newNode

currNode.setNextNode(newNode);

A -> newNode A-> newNode

So now you should have something like A -> newNode -> B. No need to ever touch C. 因此,现在您应该拥有类似A-> newNode-> B的东西。无需触摸C。

So now you can fix the backlinks and you're done. 因此,现在您可以修复反向链接,您已完成。

currNode.getNextNode().setPrevious(newNode);

set backlink from B to newNode 设置从B到newNode的反向链接

newNode.setPrevious(currNode);

set backlink from newNode to currNode 设置从newNode到currNode的反向链接

ps: I didn't test this. ps:我没有测试。 I didn't look into the if-conditions themselves, I didn't think about your indexToInsert ==1 -case, etc.. still I hope to have given you an idea where the mistake is coming from and pointed you in the right direction... 我没有亲自研究if条件,也没有考虑过您的indexToInsert ==1等。仍然希望您能知道错误的indexToInsert ==1并指出正确的地方方向...

pps: It is considered good practice to stick to the standard java naming conventions - method-names should start with lowercase letters. pps:遵循标准的Java命名约定被认为是一种好习惯-方法名应以小写字母开头。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM