好的,我的程序的这一部分的目的是获取一个未排序的对象数组列表,并根据每个对象中的getRaised()方法对其进行排序,该方法使用递归mergeSort方法返回一个整数。程序运行时没有错误,但它没有对arraylist进行排序。
click div.btn-group
这是整个班级:
public static void mergeSort(ArrayList<Runner> runners, int min, int max){
if(min < max){
int mid = (min+max)/2;
mergeSort(runners, min, mid);
mergeSort(runners, mid+1, max);
merge(runners, min, mid, max);
}
}
public static void merge(ArrayList<Runner> runners, int first, int mid, int last){
ArrayList<Runner> temp = new ArrayList<>();
temp = runners;
int f1 = first;
int l1 = mid;
int f2 = mid+1;
int l2 = last;
int index = f1;
for(int i = 0; i < runners.size(); i++){
temp.add(runners.get(i));
}
while(f1 <= l1 && f2 <= l2){
if(runners.get(f1).getRaised() < runners.get(f2).getRaised()){
temp.set(index, runners.get(f1));
f1++;
}else{
temp.set(index, runners.get(f2));
f2++;
}
index++;
}
while(f1 <= l1){
temp.set(index, runners.get(f1));
f1++;
index++;
}
while(f2<=l2){
temp.set(index, runners.get(f1));
f2++;
index++;
}
for(int i = 0; i<=runners.size();i++){
runners.set(i,temp.get(index));
}
}
答案 0 :(得分:0)
您的合并方法有多处错误:
public static void merge(ArrayList<Runner> runners, int first, int mid, int last){
ArrayList<Runner> temp = new ArrayList<>();
temp = runners; // remove that line, otherwise your original list will
// continue growing until you run out of memory
int f1 = first;
int l1 = mid;
int f2 = mid+1;
int l2 = last;
int index = f1;
for(int i = 0; i < runners.size(); i++){
temp.add(runners.get(i));
}
while(f1 <= l1 && f2 <= l2){
if(runners.get(f1).getRaised() < runners.get(f2).getRaised()){
temp.set(index, runners.get(f1));
f1++;
}else{
temp.set(index, runners.get(f2));
f2++;
}
index++;
}
while(f1 <= l1){
temp.set(index, runners.get(f1));
f1++;
index++;
}
while(f2<=l2){
temp.set(index, runners.get(f1)); // typo - should be get(f2)
f2++;
index++;
}
for(int i = 0; i<=runners.size();i++){ // should be i<runners.size()
// to avoid index out of bounds
// exception
runners.set(i,temp.get(index)); // should be i instead of index
}
}
这样可行,但效率不高,因为在每次调用merge
时,您将整个源列表复制到临时列表并返回到源列表,而应该复制的唯一索引是从头到尾的指数。
这是一个更有效的合并:
public static void merge(ArrayList<Runner> runners, int first, int mid, int last){
ArrayList<Runner> temp = new ArrayList<>();
int f1 = first;
int l1 = mid;
int f2 = mid+1;
int l2 = last;
while(f1 <= l1 && f2 <= l2){
if(runners.get(f1).getRaised() < runners.get(f2).getRaised()){
temp.add(runners.get(f1));
f1++;
}else{
temp.add(runners.get(f2));
f2++;
}
}
while(f1 <= l1){
temp.add(runners.get(f1));
f1++;
}
while(f2<=l2){
temp.add(runners.get(f2));
f2++;
}
// copy only the merged range back to runners
int index = 0;
for(int i = first; i<=last;i++){
runners.set(i,temp.get(index));
index++;
}
}
我通过将ArrayList<Runner>
更改为ArrayList<Integer>
来测试它,但它确实有效。