【问题标题】:How do I turn my custom linked list into an array?如何将我的自定义链表转换为数组?
【发布时间】:2010-10-21 03:03:36
【问题描述】:

我必须实现一个方法:

E[] toArray(E[] a) // Pass an array, convert to singly linked list, then return the array. 

来自java.utilInterface List<E>

正如我所提到的,我必须传递一个数组,将其转换为单链表,对其进行排序,然后返回该数组。

Node 类中,我可以使用它:

public Node(E v, Node<E> next) {
    // pre: v is a value, next is a reference to remainder of list
    // post: an element is constructed as the new head of list
    data = v;
    nextElement = next;
}

public Node(E v) {
    // post: constructs a new tail of a list with value v
    this(v,null);
}

public Node<E> next() {
    // post: returns reference to next value in list
    return nextElement;
}

public void setNext(Node<E> next)  {
    // post: sets reference to new next value
    nextElement = next;
}

public E value() {
    // post: returns value associated with this element
    return data;
}

public void setValue(E value) {
    // post: sets value associated with this element
    data = value;
}

我是在叫错树还是有人可以在这里帮我解决这个问题?抱歉,如果这是此类问题的错误位置。

【问题讨论】:

  • 对列表进行排序的要求从何而来?到目前为止,您在实现E[] toArray(E[] a) 方面做了哪些尝试?
  • 你为什么要把它变成一个链表,然后又变成一个数组?这只是为了锻炼吗?

标签: java collections linked-list


【解决方案1】:

以下代码将创建单链表并将其复制回数组的新副本。对于您需要确保使 \"E"\ 类型实现具有可比性的排序。 一种方法是将 \"E"\ 的通用声明符更改为 >。


    E[] toArray(E[] a)
    {
        E[] result ;
        Class<?> type ;
        Node<E> head, temp, current ;

        /*
         * Makes a copy of the original array
         */
        type = a.getClass().getComponentType() ;
        result = (E[])java.lang.reflect.Array.newInstance(type, a.length);
        for(int idx = 0; idx < a.length; idx++)
            result[idx] = a[idx] ;

        /*
         * Sort the array (selection copy)
         */
        for(int idx = 0; idx < result.length; idx++)
        {
            int best = idx ;
            for(int jdx = idx + 1; jdx < result.length; jdx++)
            {
                if (result[best].compareTo(result[jdx]) > 0)
                {
                    best = jdx ;
                }
            }
            // swap
            if (best != idx)
            {
                E temporal = result[idx] ;
                result[idx] = result[best] ;
                result[best] = temporal ;
            }
        }

        /*
         * Compose the single linked list (SORTED)
         */
        head = new Node<E>(null, null) ;

        // Create the single linked list
        current = head ;
        for(E element : result)
        {
            temp = new Node<E>(element, null) ;
            current.setNext(temp) ;
            current = current.next();
        }

        /*
         * Copy the single linked list to the array 
         * (Not needed, added just for educational purpose,
             * the result array is already SORTED)
         */

        current = head.next ;
        // copies the values to the result array
        for(int index = 0; current != null ; current = current.next)
            result[index++] = current.value();

        return result ;
    }

【讨论】:

    【解决方案2】:

    明显错误答案:

    E[] 到数组(E[] 一个) {返回一个; } // 证明我没有创建链表。

    我认为构建和排序您完全跳过的链表有一些副作用?或者返回的应该是排序后的列表,而不是数组,可能是排序后的列表被强制返回到数组中?

    【讨论】:

    • 直接从马嘴里:
    • 以正确的顺序(从第一个元素到最后一个元素)返回一个包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。如果列表适合指定的数组,则在其中返回。否则,将使用指定数组的运行时类型和此列表的大小分配一个新数组。
    • 如果列表适合指定的数组并有剩余空间(即数组的元素多于列表),则数组中紧随列表末尾的元素设置为空。 (仅当调用者知道列表不包含任何空元素时,这对确定列表的长度很有用。)
    • 缩小的唯一方法是,如果您应该在数组成员通过此过程时消除重复项或以其他方式删除它们。那么,您是否应该在数组元素通过时消除它们?它可以变得更大的唯一方法是,如果您应该发明最初不在数组中的新元素,到目前为止还没有提到。
    • 这很好。我会尽力找出答案。
    【解决方案3】:

    我希望这是你想要的:

    /**
     * You need to pass in the class of the object you are creating
     * because you can't instantiate a generic class.
     */
    public static <E> E[] toArray(E[] a, Class<E> clazz) {
        Node<E> root = null;
        Node<E> prev = null;
        Node<E> curr = null;
    
        for (E e : a) {
            curr = new Node<E>(e);
            if (prev != null) {
                prev.setNext(curr);
            }
            else {
                root = curr;
            }
            prev = curr;
        }
    
        curr =  root;
    
        // Cast is unsafe. I don't know a better way to do this.
        E[] newArray = (E[]) Array.newInstance(clazz, a.length);
        int i = 0; 
        while (curr != null) {
            newArray[i] = curr.value();
            curr = curr.next();
            i++;
        }
    
        return newArray;
    }
    

    正如我在代码中所说,我不知道如何正确实例化泛型类。有人可以纠正我吗?

    【讨论】:

    • 我很想能够纠正你,但你远远领先于我,所以我只能说尝试遵循逻辑。感谢您的意见。
    • 顺便问一下,这是 AP comp sci 作业吗?我记得在高中时做过这样的事情。我会把沉默当作默契;)
    • 抱歉打扰了。不知道我是否在正确的地方。
    • 嘿,只是说,如果我是一名老师,我会在作业到期前几天来这里。
    • 好吧,老实说,他们似乎并不在意。他们鼓励我们在线获得帮助,也可以从彼此那里获得帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 2017-07-08
    相关资源
    最近更新 更多