我正在尝试用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:
我一直在玩它,似乎共享thisQueue
,lists
和queue
。当我在thisQueue
thisQueue.add(1)
上执行某些操作时,会在整个主板上添加“1”的值。如果我在lists
上使用lists.add(1)
执行相同操作lists
中的每个节点都填充了值1。
我记得读过一些关于通过引用传递的对象值的东西(虽然不是对象本身),这与我正在经历的事情有什么关系吗?
编辑3:
我也注意到如果我在.add()
行中使用文字而不是变量,例如
thisQueue.add(value);
这些值不像EDIT 2中提到的那样重复。我尝试将变量用作int
,即使它们被声明为Int,但仍然得到相同的结果。
答案 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)。