双链表的类

时间:2010-07-23 05:21:55

标签: java linked-list

我必须编写一个类来处理没有空头或尾节点的双向链接列表。我已经修改了一些我认为应该用于双链接列表的代码,但它抛出了以下异常。如何防止发生异常以及删除空头或尾节点需要进行哪些更改?

Exception in thread "main" java.lang.NullPointerException
    at P4DLL.removeLast(P4DLL.java:105)
    at P4DLL.main(P4DLL.java:197)

代码:

class ListNode
{
    Object element;
    ListNode next;
    ListNode prev;

    public ListNode( Object anElement )
    {
        element = anElement;
        next = null;
        prev = null;
    }

    public ListNode( Object anElement,  ListNode nextPtr, ListNode prevPtr)
    {
        element = anElement;
        next = nextPtr;
        prev = prevPtr;
    }
} // end class ListNode

public class P4DLL
{

    private ListNode head;
    private ListNode tail;
    private int size;

    public P4DLL()
    {
        head = null;
        tail = null;
        size = 0;
    }

    public void addAtFirst( Object anElement )
    {
        //create a new node to be stored at the beginning of the list
        ListNode newNode = new ListNode( anElement);
        newNode.next = head;
        head = newNode;
        size++;

        if(tail == null)
            tail = head;
    }

    public void addAtLast( Object anElement )
    {
        //create a new node to be stored at the begginning of the list
        ListNode newNode = new ListNode( anElement);

        if(tail == null)
        {
            head = tail = newNode;
        }
        else
        {
            tail.next = newNode;
            tail = tail.next;
        }

        size++;
    }

    public Object removeFirst( )
    {
        //the list has no elements to remove
        if ( isEmpty( ) )
        {
            return null;
        }

        //get a ptr to the first data node
        ListNode ptr = head.next;

        //save the data in this node so it can be returned
        Object data = head.next.element;

        //link around this node
        ptr.next.prev = ptr.prev;
        ptr.prev.next = ptr.next;

        size--;

        //return the data in this node
        return data;
    }

    public Object removeLast( )
    {
        //if the list has no elements there is nothing to return
        if ( isEmpty( ) )
        {
            return null;
        }

        //get a ptr to the last data node
        ListNode ptr = tail.prev;

        //save the data in this node so it can be returned
        Object data = tail.element;

        //link around this node
        ptr.next.prev = ptr.prev; // P4DLL.java:105
        ptr.prev.next = ptr.next;

        size--;

        //return the data in this node
        return data;
    }

    public Object getFirstElement( )
    {
        if ( size == 0 )
        {
            return null;
        }
        else
        {
            return head.next.element;
        }
    }

    public Object getLastElement( )
    {
        if ( size == 0 )
            return null;
        else
            return tail.prev.element;
    }

    public int getNumElements( )
    {
        return size;
    }

    public boolean isEmpty( )
    {
        return size == 0;
    }

    public void displayList( )
    {
        if ( isEmpty( ) )
        {
            System.out.println ( "The list is empty.\n" );
        }
        else
        {
            System.out.println ( this.toString( ) );
        }
    }   

    public String toString( )
    {
        String returnStr = "";

        if ( ! isEmpty( ) )
        {
            ListNode ptr = head.next;

            while ( ptr != tail )
            {
                returnStr += ptr.element.toString ();
                returnStr += "\n";
                ptr = ptr.next;
            }
        }

        return returnStr;
    }

 // makes the list empty
 public void clear( )
 {
     if ( ! isEmpty( ) )
     {
         head.next = tail;
         tail.prev = head;
         size = 0;
     }
 }

  public static void main ( String[] args )
  {
        P4DLL list = new P4DLL( );
        list.addAtFirst ( "Abe" );
        list.addAtFirst ( "Beth");
        list.addAtLast ( "Ed" );
        list.displayList ();
        System.out.println( "The number of elements in this list is "
                            + list.getNumElements() );

        System.out.println( "\nNow remove the last element and display.\n" );
        list.removeLast(); // P4DLL.java:197
        list.displayList ();
  }

}

1 个答案:

答案 0 :(得分:5)

您的代码在NullPointerException方法中生成removeLast()。修理它! :-D

您似乎从某处复制了此代码,包括拼写错误:
http://www.cramster.com/answers-jul-09/computer-science/doubly-linked-list-xi5te-program-implements-class-doubly-linked_619688.aspx

当前编写的代码假设是头节点和尾节点。你需要重新编写这种方法(可能还有其他方法)来解释这个新的现实。

修改

我刚刚查看了代码和我在上面链接中找到的代码之间的差异。我的建议是完全废弃它并从头开始编写链表。它不仅是在假设头部和尾部节点,它还打破至少以一种方式编写的。您自己已经注意到这一点,因为提供的size--中缺少removeLast(),您必须自己添加它。还有评论的问题在谈论“指针”,拼写错误等等。

这是一个起点。这是removeLast()

的有效实施
public Object removeLast( ) {
    if (size == 0) return null;
    final Object result = last.element;
    if (size == 1)
        first = last = null;
    else {
        last = last.prev;
        last.next = null;
    }
    size--;
    return result;
}

由于您没有使用头部或尾部节点,因此我使用了名为firstlast的字段,以便更清晰。