linkedlist实现添加方法

时间:2016-01-28 18:06:09

标签: java

我正在为网上课程实现链接列表,而且我的添加功能似乎有问题。当我尝试添加第一个元素时,Eclipse会输出null,而对于第二个元素,Eclipse会显示错误。 (我假设因为第一个元素从未添加过,所以不能再添加第二个元素。)

这是我的链接列表的实现:

    package textgen;

    import java.util.AbstractList;

    public class MyLinkedList<E> extends AbstractList<E> {
        LLNode<E> head;
        LLNode<E> tail;
        int size;

        /** Create a new empty LinkedList */
        public MyLinkedList() {

            size = 0;

            head = new LLNode<E>();
            tail = new LLNode<E>();
            head.next = tail;
            tail.prev = head;

        }

        /**
         * Appends an element to the end of the list
         * @param element The element to add
         */
        public boolean add(E element ) 
        {

            add(size, element);

            return false;
        }

        /** Get the element at position index 
         * @throws IndexOutOfBoundsException if the index is out of bounds. */
        public E get(int index)  throws IndexOutOfBoundsException
        { 

            if(index >= this.size){
                throw new IndexOutOfBoundsException("Your index is out of bounds!");
            }

            LLNode<E> lGet = head;
            for(int i = 0; i < index + 1; i++){
                lGet = lGet.next;
            }

            return  lGet.data;   
        }


        public void printList(){

            LLNode lTemp = head;

            while(lTemp.next != tail){
                System.out.println(lTemp.next.data);
                lTemp = lTemp.next;
            }
        }




        /**
         * Add an element to the list at the specified index
         * @param The index where the element should be added
         * @param element The element to add
         */

        public void add(int index, E element )  throws IndexOutOfBoundsException
        {
            if(index > this.size){   
                throw new IndexOutOfBoundsException("Oops!  Out of bounds!");
        }

                else{
                    LLNode<E> nAdd = new LLNode<E>(element);
                    LLNode<E> nIt = null;


                    if(index <= size/2)  //   if  the index is closer to the start from the beginning of the list
                {
                    nIt = head;

                        for(int i = 0; i < index + 1; i++){
                            nIt = nIt.next;
                        }
                    }


                else {

                    nIt = tail;

                        for(int i = this.size; i > index; i--){
                            nIt = nIt.prev;
                        }

                    }

                    nIt.prev.next.prev = nAdd;    
                    nAdd.next = nIt.prev.next;
                    nIt.prev.next = nAdd;
                    nAdd.prev = nIt.prev;

            size++;
                }   

        }


        /** Return the size of the list */
        public int size()      

        {
            return size;
        }

        /** Remove a node at the specified index and return its data element.
         * @param index The index of the element to remove
         * @return The data element removed
         * @throws IndexOutOfBoundsException If index is outside the bounds of the list
         * 
         */
        public E remove(int index) 
        {
            // TODO: Implement this method



            size--;

            return null;
        }

        /**
         * Set an index position in the list to a new element
         * @param index The index of the element to change
         * @param element The new element
         * @return The element that was replaced
         * @throws IndexOutOfBoundsException if the index is out of bounds.
         */
        public E set(int index, E element) 
        {
            // TODO: Implement this method
            return null;
        }   
    }

    class LLNode<E> 
    {
        LLNode<E> prev;
        LLNode<E> next;
        E data;

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

        public LLNode(E e) 
        {
            this.data = e;
            this.prev = null;
            this.next = null;
        }

    }

This is the main:

包textgen;

public class fixAdd {


    public static void main(String [] Arg){

        MyLinkedList<String>  ll = new MyLinkedList<String>();
        ll.add(0, "happy");
    ll.add(1, "gilda");
        System.out.println(ll);

    }
}

And this is the error printed:

Exception in thread "main" java.lang.NullPointerException
    at textgen.MyLinkedList.get(MyLinkedList.java:57)
    at java.util.AbstractList$Itr.next(Unknown Source)
    at java.util.AbstractCollection.toString(Unknown Source)
    at java.lang.String.valueOf(Unknown Source)
    at java.io.PrintStream.println(Unknown Source)
    at textgen.fixAdd.main(fixAdd.java:11)

我已经多次使用我的添加方法,并将其与我在网上找到的其他实现进行比较,一切看起来都井井有条。我完全感到困惑,并希望得到任何帮助。谢谢!

3 个答案:

答案 0 :(得分:1)

您应首先尝试实施更简单的add,而不是进行size / 2优化。

您的代码存在一些问题:

  • 在初始化时不创建虚拟节点,用null
  • 初始化它们
  • get方法中的循环应为for(int i = 0; i < index; i++)
  • 您无法更新add方法
  • 中的尺寸

编辑:更改add方法以涵盖所有情况:

public void add(int index, E element)
{
    if (index > size)
    {
        throw new IndexOutOfBoundsException("Oops!  Out of bounds!");
    }

    LLNode<E> node = new LLNode<E>(element);

    //Add first and last
    if(size == 0)
    {
        head = tail = node;
    }
    else
    {
        //Add first
        if(index == 0)
        {
            node.next = head;
            head.prev = node;
            head = node;
        }

        //Add last
        else if(index  == size)
        {
            node.prev = tail;
            tail.next = node;
            tail = node;
        }

        //Add between
        else
        {
            LLNode<E> current = this.head;

            for(int i = 0; i < index; i++)
            {
                current = current.next;
            }
            node.next = current;
            node.prev = current.prev;
            current.prev.next = node;
        }
    }
    size++;
}

答案 1 :(得分:0)

此实施的多个问题:

  1. 初始化列表(构造函数)时,您将head和tail设置为空节点。你不应该这样做,它使你的列表大小为2,有两个空元素。
  2. 主要打印引发异常,反过来调用get()方法(通过调用AbstractList.toString()
  3. add(E element)您正在调用add(size, element);并将size作为索引传递,稍后检查if(index > this.size)是否实际问size > size remove() 1}} - 毫无意义。
  4. nIt.prev.next.prev = nAdd; nAdd.next = nIt.prev.next; nIt.prev.next = nAdd; nAdd.prev = nIt.prev; 实施中,你只是缩小了尺寸 - 这还不够好,你也应该向后移动尾部(如果列表大小为1 - 也要处理头部)。
  5. 这是主要问题:以下行中的插入逻辑不正确:
  6. AbstractList

    两个建议:

    • 不要继承tail - 毕竟您正在创建自己的实施
    • 从简单开始,忘记 var $table = $('<table>' + trHTML + '</table>'); 或尝试从最后插入以提高效率。只有在你有一个简单的实现工作后 - 尝试改进它。

答案 2 :(得分:-1)

请尝试以下代码:

public void insert(int index, T item)
{
if(index == size())
{
    add(item);
}
else if(index == 0)
{
    MyNode<T> temp = new MyNode<T>();
    temp.data = item;
    temp.next = head;
    head.previous = temp;
    head = temp;
    count++;
}
temp = head;
for(int i = 0; i < index-1; i++)
{
    temp = temp.next;
    MyNode<T> myNode = new MyNode<T>();
    myNode.data = item;
    myNode.next = temp.next;
    temp.next = myNode;
    count++;
}
}