Java - 队列LL实现为每个LL节点重复队列

时间:2013-11-30 02:04:55

标签: java linked-list queue radix-sort

我正在尝试用Java编写RadixSort的一个例子,虽然我理解算法是如何工作的,但是我遇到了一些链接列表队列的实现问题。

我相信我的问题是当我使用新队列更新第n个位置的链接列表作为其值时。我相信我为每个节点更新使用相同的队列,这导致我为链表中的每个节点获取相同的值。

所以当从int[] theArray = {4,3,5,9,7,2,4,1,6,5};

数组开始时

我最终得到了一个包含10个节点的链表,每个节点都包含一个队列:{4,3,5,9,7,2,4,1,6,5}

我认为通过使用new关键字,它会创建一个新的实例,但它似乎每次迭代都会遗留旧的值。

有人可以解释或指出我正确的方向来理解为什么会这样吗?

编辑:(忘了附上代码)

package radixsort;
import java.util.*;
/**
 * @author dlanz
 */
public class RadixSort {

    public static void main(String[] args) {

        int[] theArray = {4,3,5,9,7,2,4,1,6,5};

        RadixSort theSort = new RadixSort();

        System.out.println(Arrays.toString(theArray)); //Outputs the original array
        theSort.sort(theArray);
        System.out.println(Arrays.toString(theArray)); //Outputs the original array (no modifictions)
    }



    public void sort(int[] theArray) {
        int significant;
        int curVal;    
        int modulo = 10;
        int ofInterest = 1;

        LinkedList<Queue> lists = new LinkedList<>();
        Queue<Integer> queue = new LinkedList<>();

        int max = theArray[0];
        for(int i = 0; i < theArray.length; i++) {
            if ( theArray[i] > max) {
                  max = theArray[i];
            }
        }
        significant = String.valueOf(max).length();
        Queue<Integer> thisQueue;
        for(int j = 1; j <= significant; j++){

            lists.clear();
            for(int i = 0; i < 10; i++){
                lists.add(i, queue);
            }
            System.out.println(lists); //Outputs a list of 10 elements each with a value of null
            for(int value : theArray){
                  curVal = value % modulo;
                  curVal = curVal / ofInterest;
                  System.out.println(curVal); //Correctly outputs the expected result
                  System.out.println(lists.get(curVal)); //With each iteration this outputs 10 elements each with a queue of all values.

                  thisQueue = new LinkedList<>();
                  thisQueue = lists.get(curVal);
                  thisQueue.add(value);

                  lists.set(curVal, thisQueue);// This seems to insert the generated queue into every linked lists node.
            }
            int k = 0;
            for(int i = 0; i < 10; i++){
                Queue<Integer> curQueue = lists.get(i);
                if(!curQueue.isEmpty()){
                    theArray[k] = curQueue.remove();
                    k++;
                }
            }
            ofInterest = ofInterest * 10;
            modulo = modulo * 10;
        }
    }
}

编辑2:

我一直在玩它,似乎共享thisQueuelistsqueue。当我在thisQueue thisQueue.add(1)上执行某些操作时,会在整个主板上添加“1”的值。如果我在lists上使用lists.add(1)执行相同操作lists中的每个节点都填充了值1。

我记得读过一些关于通过引用传递的对象值的东西(虽然不是对象本身),这与我正在经历的事情有什么关系吗?

编辑3:

我也注意到如果我在.add()行中使用文字而不是变量,例如

thisQueue.add(value);

这些值不像EDIT 2中提到的那样重复。我尝试将变量用作int,即使它们被声明为Int,但仍然得到相同的结果。

1 个答案:

答案 0 :(得分:0)

奇怪的是,我很欣赏没有人回答这个问题。我在创建一组示例代码并制定一个不太具体的问题时自己想出来。但是很长一段时间我都不会忘记这一点。

发生的事情是我循环遍历的代码部分,并在我的链接列表中创建节点0-9

for(int i = 0; i < 10; i++){
    lists.add(i, queue);
}

我正在添加对同一个队列的引用。所以无论使用其他Queues / .clear(),我基本上都是在这一行上提取原始队列的引用

thisQueue = lists.get(curVal);

虽然我在此过程中做了一些改动,但真正需要做的就是将循环更改为

for(int i = 0; i < 10; i++){
    queue = new LinkedList<>();
    lists.add(i, queue);
}

并更改

Queue<Integer> queue = new LinkedList<>();

只是

Queue<Integer> queue

我曾想过显式创建10个独立队列,然后在代码中使用开关来决定应该使用哪个队列。这似乎不是很灵活,而且非常乏味。与此同时,我意识到为每次迭代创建一个新的队列是非常昂贵的。我将创建尽可能多的数组中的对象,在本例中为10,但可能是100,1000,1000000。通过使用(纠正我,如果我错了)匿名对象我只能创建尽可能多的对象根据需要(链接列表中的每个元素为1)。