Как удалить текущий узел в односвязном списке? - PullRequest
1 голос
/ 07 ноября 2011

Я пытаюсь закончить программу, и я пойман на месте. Мой метод deleteCurrentNode работает только частично. По какой-то причине, когда я пытаюсь просмотреть связанный список, чтобы найти currentNode, он никогда не находит его. Может кто-нибудь дать мне совет, как заставить его работать?

Сам метод проверяет 4 условия:

  1. Если список пуст.
  2. Если currentNode равен нулю.
  3. Если currentNode является первым узлом в списке.
  4. Если currentNode находится где-то в списке.

Другие условия работы (насколько мне известно). 4, где проблема.

public class LinkedList 
{
private Node currentNode;
private Node firstNode;
private int nodeCount;

public static void main(String[] args)
 {
 LinkedList test;
 String dataTest;
 test = new LinkedList();
 dataTest = "abcdefghijklmnopqrstuvwxyz";
 for(int i=0; i< dataTest.length(); i++) { test.insert(new String(new char[] { dataTest.charAt(i) }));  }
 System.out.println("[1] "+ test);

  for(int i=0; i< dataTest.length(); i++) { test.deleteCurrentNode(); }
  System.out.println("[2] "+test);

  for(int i=0; i< dataTest.length(); i++)
  {
  test.insertBeforeCurrentNode(new String(new char[] { dataTest.charAt(i) }));
   if(i%2 == 0) { test.first(); } else { test.last(); }
  }

  System.out.println("[3] "+test);

  for(int i=0; i< dataTest.length(); i++) { test.last(); test.deleteCurrentNode(); }
      System.out.println("[4] "+test);


      for(int i=0; i< dataTest.length(); i++) { test.insert(new String(new char[] { dataTest.charAt(i) })); test.last(); }
      System.out.println("[5] "+test);

    while(!test.isEmpty()) { test.deleteFirstNode(); }
    System.out.println("[6] "+test);

   for(int i=0; i< dataTest.length(); i++) { test.insert(new String(new char[] { dataTest.charAt(i) })); test.last(); }
  System.out.println("[7] "+test);

   while(!test.isEmpty()) { test.deleteFirstNode(false); }
   System.out.println("[8] "+test);

   for(int i=0; i< dataTest.length(); i++) { test.insertBeforeCurrentNode(new String(new char[] { dataTest.charAt(i) })); test.first(); }
   System.out.println("[9] "+test);
 }

public LinkedList()
{
    setListPtr(null);
    setCurrent(null);
    nodeCount = 0;
}

public boolean atEnd()
{
    //checkCurrent();
    return getCurrent().getNext() == null;      
}

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

public void first()
{
    setCurrent(getListPtr());
}

public void next()
{
    checkCurrent();
    if (atEnd()) {throw new InvalidPositionInListException("You are at the end of the list. There is no next node. next().");}
    setCurrent(this.currentNode.getNext());
}

public void last()
{
    if (isEmpty()) {throw new ListEmptyException("The list is currently empty! last()");}

    while (!atEnd())
    {
        setCurrent(getCurrent().getNext());
    }

}

public Object getData()
{
    return getCurrent().getData();
}

public void insertBeforeCurrentNode(Object bcNode) //beforeCurrentNode
{
    Node current;
    Node hold;
    boolean done;
    hold = allocateNode();
    hold.setData(bcNode);
    current = getListPtr();
    done = false;
    if (isEmpty())
    {
        setListPtr(hold);
        setCurrent(hold);       
    }

    else if (getCurrent() == getListPtr())
    {
    //  System.out.println("hi" + hold);
        hold.setNext(getCurrent());
        setListPtr(hold);
    }

    else if (!isEmpty() && getCurrent() != getListPtr())
    {
        while (!done && current.getNext() != null)
        {
            //System.out.println("in else if " + hold);
            if (current.getNext() == getCurrent())
            {
                //previous.setNext(hold);
                //System.out.println("hi"+ "yo" + " " + getListPtr());
                hold.setNext(current.getNext());
                current.setNext(hold);
                done = true; 
            }

            //previous = current;
            current = current.getNext();
        }

    }
    //System.out.println("current " + getCurrent());
    //System.out.println("pointer " + getListPtr());

}

public void insertAfterCurrentNode(Object acNode) //afterCurrentNode
{
    Node hold;
    hold = allocateNode();
    hold.setData(acNode);
    if (isEmpty())
    {
        setListPtr(hold);
        setCurrent(hold);
        //System.out.println(hold + " hi");
    }

    else 
    {
        //System.out.println(hold + " hia");
        hold.setNext(getCurrent().getNext());
        getCurrent().setNext(hold);
    }
}

public void insert(Object iNode)
{
    insertAfterCurrentNode(iNode);
}

public Object deleteCurrentNode()
{
    //System.out.println("in delete current");
    Object nData;
    Node previous;

    if (isEmpty()) {throw new ListEmptyException("The list is currently empty! last()");} //if list is empty throw exception

    checkCurrent(); //check if currentNode is null, method throws exception if it is.

    nData = getCurrent().getData();

    if (getCurrent() == getListPtr())
    {
        setListPtr(getCurrent().getNext());
        setCurrent(getCurrent().getNext());
        nodeCount = nodeCount -1;
    }

    else 
    {
        previous = getListPtr();
        while (previous.getNext() != getCurrent())
        {
            previous = previous.getNext();
            //System.out.println("test"+ previous);
        }


        if (getCurrent().getNext() != null)
        {
            previous.setNext(null);
        }

        previous.setNext(getCurrent().getNext());       }

    return nData;
}

public Object deleteFirstNode(boolean toDelete)
{
    if (toDelete)
    {
        setListPtr(null);
    }
    return getListPtr();
}

public Object deleteFirstNode()
{
    Object deleteFirst;
    deleteFirst = deleteFirstNode(true);
    return deleteFirst;
}

public int size()
{
    return this.nodeCount;
}

public String toString()
{
    String nodeString;
    Node sNode;
    sNode = getListPtr();
    //System.out.println(nodeCount);
    nodeString = ("List contains " + nodeCount + " nodes");
    while (sNode != null)
    {
        nodeString = nodeString + " " +sNode.getData();
        sNode = sNode.getNext();
    }   
    return nodeString;
}

private Node allocateNode()
{
    Node newNode;
    newNode = new Node();
    nodeCount = nodeCount + 1;
    return newNode;
}

private void deAllocateNode(Node dNode)
{
    dNode.setData(null);
}

private Node getListPtr()
{
    return this.firstNode;
}

private void setListPtr(Node pNode)
{
     this.firstNode = pNode;
}

private Node getCurrent()
{
    return this.currentNode;
}

private void setCurrent(Node cNode)
{
    this.currentNode = cNode;
}

private void checkCurrent()
{
    if (getCurrent() == null) {throw new InvalidPositionInListException("Current node is null and is set to an invalid position within the list! checkCurrent()");}
}

/**NODE CLASS ----------------------------------------------*/

    private class Node 
    {
        private Node next; //serves as a reference to the next node 
        private Object data;

        public Node()
        {
            this.next = null;
            this.data = null;
        }


        public Object getData()
        {
            return this.data;
        }

        public void setData(Object obj)
        {
            this.data = obj;
        }

        public Node getNext()
        {
            return this.next;
        }

        public void setNext(Node nextNode)
        {
            this.next = nextNode;
        }

        public String toString()
        {
            String nodeString;
            Node sNode;
            sNode = getListPtr();
            //System.out.println(nodeCount);
            nodeString = ("List contains " + nodeCount + " nodes");
            while (sNode != null)
            {
                nodeString = nodeString + " " +sNode.getData();
                sNode = sNode.getNext();
            }   
            return nodeString;
        }
    }


 }

[4] должно читаться так же, как [2] (список содержит 0 узлов.)

Примечание: не могу использовать больше переменных / методов / и т.д., которые у меня уже есть. И я не могу использовать головные узлы.

Ответы [ 3 ]

1 голос
/ 08 ноября 2011

Вы можете рассмотреть возможность защиты от null в вашем коде.Лучше не делать предположений.

Например,

public boolean atEnd()
{
    return getCurrent().getNext() == null;

}

может быть лучше написано как

public boolean atEnd()
{
   if (getCurrent() != null)
   {
     return getCurrent().getNext() == null;
   }
   return true;
}

Это не обязательно лучший способ сделать это;Вы могли бы хотеть бросить NoCurrentNodeException или что-то.Это зависит от семантики, которую вы ищете.

В любом случае, вы не будете похоронены в NullPointerExceptions.

1 голос
/ 09 ноября 2011
public class LinkedList 
{
private Node currentNode;
private Node firstNode;
private int nodeCount;


public static void main(String[] args)
 {
  String     data;
  Object     hold;
  LinkedList list;

  data = "abcdefghijklmnopqrstuvwxyz";
  hold = null;
  list = new LinkedList();

  for(int i=0; i< data.length(); i++) { list.insert(new String(new char[] { data.charAt(i) }));  }
  System.out.println("[1] "+list);

  for(int i=0; i< data.length(); i++) { list.deleteCurrentNode(); }
  System.out.println("[2] "+list);

  for(int i=0; i< data.length(); i++)
  {
   list.insertBeforeCurrentNode(new String(new char[] { data.charAt(i) }));
   if(i%2 == 0) { list.first(); } else { list.last(); }
  }

  System.out.println("[3] "+list);

  for(int i=0; i< data.length(); i++) { list.last(); list.deleteCurrentNode(); }
  System.out.println("[4] "+list);


  for(int i=0; i< data.length(); i++) { list.insert(new String(new char[] { data.charAt(i) })); list.last(); }
  System.out.println("[5] "+list);

  while(!list.isEmpty()) { list.deleteFirstNode(); }
  System.out.println("[6] "+list);

  for(int i=0; i< data.length(); i++) { list.insert(new String(new char[] { data.charAt(i) })); list.last(); }
  System.out.println("[7] "+list);

  while(!list.isEmpty()) { list.deleteFirstNode(false); }
  System.out.println("[8] "+list);

  for(int i=0; i< data.length(); i++) { list.insertBeforeCurrentNode(new String(new char[] { data.charAt(i) })); list.first(); }
  System.out.println("[9] "+list);

  list.first();
  list.next();
  list.deleteFirstNode(true);
  list.deleteCurrentNode();
  for(int i=0; i< 5; i++)  { hold = list.getData();  list.next(); }
  for(int i=0; i< 10; i++) { list.next();   }
  list.insertAfterCurrentNode(hold);
  list.first();
  list.next();
  hold = list.getData();
  list.deleteCurrentNode();
  for(int i=0; i<9; i++)  {list.deleteCurrentNode();  list.last(); }
  list.insert(hold);
  list.first();
  list.next();
  list.next();
  list.next();
  list.deleteFirstNode(false);
  hold = list.getData();
  list.deleteCurrentNode();
  list.last();
  list.insertAfterCurrentNode(hold);
  list.deleteFirstNode();
  list.deleteFirstNode();
  hold = list.getData();
  list.deleteFirstNode();
  list.last();
  list.insertBeforeCurrentNode(hold);
  list.first();
  for(int i=0; i<6; i++) { list.next(); }
  hold = list.getData();
  list.deleteCurrentNode();
  list.last();
  list.insertBeforeCurrentNode(hold);
  list.first();
  list.deleteCurrentNode();
  list.deleteCurrentNode();
  hold = list.getData();
  list.deleteCurrentNode();
  for (int i=0; i< 7; i++) { list.next(); }
  list.insertBeforeCurrentNode(hold);
  for (int i=0; i< 4; i++) { list.first(); list.deleteCurrentNode(); }
  System.out.println("\n\n"+list);


 }

public LinkedList()
{
    setListPtr(null);
    setCurrent(null);
    nodeCount = 0;
}

public boolean atEnd()
{
    if (getCurrent() != null)
       {
         return getCurrent().getNext() == null;
       }
       return true;

}

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

public void first()
{
    setCurrent(getListPtr());
}

public void next()
{
    checkCurrent();
    if (atEnd()) {throw new InvalidPositionInListException("You are at the end of the list. There is no next node. next().");}
    setCurrent(this.currentNode.getNext());
}

public void last()
{
    if (isEmpty()) {throw new ListEmptyException("The list is currently empty! last()");}

    while (!atEnd())
    {
        setCurrent(getCurrent().getNext());
    }

}

public Object getData()
{
    return getCurrent().getData();
}

public void insertBeforeCurrentNode(Object bcNode) //beforeCurrentNode
{
    Node current;
    Node hold;
    boolean done;
    hold = allocateNode();
    hold.setData(bcNode);
    current = getListPtr();
    done = false;
    if (isEmpty())
    {
        setListPtr(hold);
        setCurrent(hold);       
    }

    else if (getCurrent() == getListPtr())
    {
    //  System.out.println("hi" + hold);
        hold.setNext(getCurrent());
        setListPtr(hold);
    }

    else if (!isEmpty() && getCurrent() != getListPtr())
    {
        while (!done && current.getNext() != null)
        {
            //System.out.println("in else if " + hold);
            if (current.getNext() == getCurrent())
            {
                //previous.setNext(hold);
                //System.out.println("hi"+ "yo" + " " + getListPtr());
                hold.setNext(current.getNext());
                current.setNext(hold);
                done = true; 
            }

            //previous = current;
            current = current.getNext();
        }

    }
    //System.out.println("current " + getCurrent());
    //System.out.println("pointer " + getListPtr());

}

public void insertAfterCurrentNode(Object acNode) //afterCurrentNode
{
    Node hold;
    hold = allocateNode();
    hold.setData(acNode);
    if (isEmpty())
    {
        setListPtr(hold);
        setCurrent(hold);
        //System.out.println(hold + " hi");
    }

    else 
    {
        //System.out.println(hold + " hia");
        hold.setNext(getCurrent().getNext());
        getCurrent().setNext(hold);
    }
}

public void insert(Object iNode)
{
    insertAfterCurrentNode(iNode);
}

public Object deleteCurrentNode()
{
    //System.out.println("in delete current");
    Object nData;
    Node previous;

    if (isEmpty()) {throw new ListEmptyException("The list is currently empty! last()");} //if list is empty throw exception

    checkCurrent(); //check if currentNode is null, method throws exception if it is.

    nData = getCurrent().getData();

    if (getCurrent() == getListPtr())
    {
        setListPtr(getCurrent().getNext());
        setCurrent(getCurrent().getNext());
        nodeCount = nodeCount -1;
    }

    else 
    {
        previous = getListPtr();
        //System.out.println(getCurrent());
        //System.out.println(previous + "ptrb ");
        while (previous.getNext() != getCurrent())
        {
            previous = previous.getNext();
            //System.out.println("test"+ previous);
        }

        //System.out.println(previous.getNext() == getCurrent());

        if (previous.getNext() == getCurrent())
        {
            //System.out.println("say hi");
            previous.setNext(getCurrent().getNext());
            deAllocateNode(getCurrent());
            setCurrent(previous);
            nodeCount = nodeCount - 1;
        }

        previous.setNext(getCurrent().getNext());

    }

    return nData;
}

public Object deleteFirstNode(boolean toDelete)
{
    if (toDelete)
    {
        setCurrent(getListPtr().getNext());
    }
    deAllocateNode(getListPtr());
    setListPtr(getListPtr().getNext());

    nodeCount = nodeCount - 1;
    return getListPtr();
}

public Object deleteFirstNode()
{
    Object deleteFirst;
    deleteFirst = deleteFirstNode(true);
    //System.out.println("called");
    return deleteFirst;
}

public int size()
{
    return this.nodeCount;
}

public String toString()
{
    String nodeString;
    Node sNode;
    sNode = getListPtr();
    //System.out.println(nodeCount);
    nodeString = ("List contains " + nodeCount + " nodes");
    while (sNode != null)
    {
        nodeString = nodeString + " " +sNode.getData();
        sNode = sNode.getNext();
    }   
    return nodeString;
}

private Node allocateNode()
{
    Node newNode;
    newNode = new Node();
    nodeCount = nodeCount + 1;
    return newNode;
}

private void deAllocateNode(Node dNode)
{
    dNode.setData(null);
}

private Node getListPtr()
{
    return this.firstNode;
}

private void setListPtr(Node pNode)
{
     this.firstNode = pNode;
}

private Node getCurrent()
{
    return this.currentNode;
}

private void setCurrent(Node cNode)
{
    this.currentNode = cNode;
}

private void checkCurrent()
{
    if (getCurrent() == null) {throw new InvalidPositionInListException("Current node is null and is set to an invalid position within the list! checkCurrent()");}
}

/**NODE CLASS ----------------------------------------------*/

    private class Node 
    {
        private Node next; //serves as a reference to the next node 
        private Object data;

        public Node()
        {
            this.next = null;
            this.data = null;
        }


        public Object getData()
        {
            return this.data;
        }

        public void setData(Object obj)
        {
            this.data = obj;
        }

        public Node getNext()
        {
            return this.next;
        }

        public void setNext(Node nextNode)
        {
            this.next = nextNode;
        }

        public String toString()
        {
            String nodeString;
            Node sNode;
            sNode = getListPtr();
            //System.out.println(nodeCount);
            nodeString = ("List contains " + nodeCount + " nodes");
            while (sNode != null)
            {
                nodeString = nodeString + " " +sNode.getData();
                sNode = sNode.getNext();
            }   
            return nodeString;
        }
    }


  }

Большое спасибо всем за ваш вклад. Они помогли мне решить мою проблему (хотя и немного неясно).

Я отвечаю на свой вопрос, чтобы, если у кого-то еще возникла подобная проблема, он мог использовать ее в качестве справочного пособия.

Еще раз спасибо.

1 голос
/ 07 ноября 2011

, если у вас есть класс Node, представляющий один узел списка, например:

public class Node{
public Object value;
public Node next;

public Node(){

}

public Node(Object p){
    value= p;
}

public String toString(){
    return "" + this.value.toString();
}
}

Чем у вас в реализации List (скажем, MyList) будет (методы только для удаления):

public class MyList{
  private Node head;

public Object removeFirst(){
    if(head == null){
        return null;
    }

    Object o= head.value;
    head= head.next;
    return o;
}

    // remove by index
public Object remove(int i){
    int n= this.size();
    if(i<0 || i>=n){
        return null;
    }

    if(i==0){
        return this.removeFirst();
    }

    int k=0;
    Node t= head;

    while(k < i-1){
        t= t.next;
        k= k+1;
    }

    Object o= t.next.value;
    t.next= t.next.next;

    return o;
}

    //remove by object
    public boolean remove(Object o){
    int k= this.indexOf(o);
    if(k<0){
        return false;
    }   
    this.remove(k);

    return true;
}

    //not necessary, but you may study the logic
    public Object removeLast(){
    Object o= null;
    if(head!=null){
        if(head.next==null){
            o= head.value;
            head= null;
        }else{
            Node t= head.next;
            while(t.next.next != null){
                t= t.next;
            }
            o= t.next.value;
            t.next= null;
        }
    }
    return o;
}
 }

Изменить: у вас есть некоторые проблемы, когда ваш массив содержит только 1 элемент.

Например, в вашем методе last () ->

    while (!atEnd()) {
        setCurrent(getCurrent().getNext());
    }
...