我需要实现此算法,在每次递归调用时创建一个新的ArrayList对象。
我的起始数组按此顺序包含整数“20,40,10,30,50,5”,排序后我有5,5,5,5,5,5
。我认为问题出现在递归调用中,最后是SelectionSort
的cicle,因为删除了最后一个因为我注意到第一个元素是正确排序的。
import java.util.*;
public class SelectionSort {
//var
public ArrayList<Integer> arr ;
//constructor
public SelectionSort(ArrayList<Integer> arr){
this.arr = arr;
}
public ArrayList<Integer> getarraylist() {
return arr;
}
public void sort(){
//position of the last sorted element
int minimum =0;
if (arr.size() <=0 ) return;
for ( int j = 1; j < arr.size()-1; j++ ) {
if (arr.get(j) < arr.get(0) ) {
minimum = j;
//swap element 0 and minimum
int temp = arr.get(0);
arr.set(0, arr.get(minimum));
arr.set(minimum, temp);
}
}
//recursive call, new array without first element (already sorted)
ArrayList<Integer> arr2 = new ArrayList<>(arr.subList(1,arr.size()));
SelectionSort s2 = new SelectionSort(arr2);
s2.sort();
for(int i=0;i<s2.getarraylist().size();i++) {
arr.set(i, s2.getarraylist().get(i));
}
}
驱动程序类
public class Main {
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<Integer (Arrays.asList(20,40,10,30,50,5));
System.out.println("\n ARRAY ELEMENTS \n ");
for (int i: arr) {
System.out.println(i);
}
System.out.println("\n SORTED ELEMENTS \n ");
SelectionSort s = new SelectionSort(arr);
s.sort();
for (int i: s.getarraylist()) {
System.out.println(i);
}
}
}
答案 0 :(得分:4)
你的算法实际上有两个错误,它们一起导致观察到的输出。
第一个错误是在for
- 循环中确定最小元素:
for ( int j = 1; j < arr.size()-1; j++ ) { ...
您过早终止一个元素,即从不考虑最后一个元素。因此,在第一次迭代之后,5
是ArrayList
中的最后一个元素。实际上,它是ArrayList
中每个的最后一个元素。修复方法是不在1
- 条件:
for
for ( int j = 1; j < arr.size(); j++ ) { ...
第二个错误发生在您的上一个for
循环中,您将i
的索引s2
中的值复制到i
的索引arr
。您忽略了s2
是一个比arr
短的元素的事实。因此,唯一没有覆盖的元素是最后一个元素。解决方法是从i
获取s2
个元素,但在i + 1
的{{1}}索引处得到它:
arr
现在让我们看看这两个错误如何导致观察到的输出。由于
arr.set(i + 1, s2.getarraylist().get(i));
中的最后一个元素永远不会被覆盖所有元素都具有相同的值(在您的测试用例中:ArrayList
)。
对您的代码的一些评论:
5
是多余的,可以替换为minimum
。如果使用j
替换ArrayList
中SelectionSort
的所有出现,您实际上可以将代码的最后部分简化为:
List
// remove the line declaring arr2, it is no longer needed
SelectionSort s2 = new SelectionSort(arr.subList(1, arr.size()));
s2.sort();
// last for-loop not needed anymore, method ends here
之后或(
或)
之前写下空白,有时则不会。看看你更喜欢什么,并统一使用它。{
- &gt; getarraylist()
)答案 1 :(得分:1)
上一次循环:
for(int i=0;i<s2.getarraylist().size();i++) {
arr.set(i, s2.getarraylist().get(i));
}
这会覆盖具有相同编号的每个元素。 (为什么你得到了所有5&#39; s)这是因为你只迭代到倒数第二个元素(arr.size()-1
)。然后复制行中的元素:
ArrayList<Integer> arr2 = new ArrayList<>(arr.subList(1,arr.size()));
最后,您只复制(5)上的最后一个元素,然后将其复制到最终ArrayList
arr
。
每次调用SelectionSort
方法时,也会创建另一个sort
对象。这不好。
这是我写的代码:
public void sort(List<Integer> list){
//position of the last ordered element
int minimum =0;
if (list.size() <=0 ) return;
for ( int j = 1; j < list.size(); j++ ) {
if (list.get(j) < list.get(0) ) {
minimum = j;
//swap element 0 and minimum
int temp = list.get(0);
list.set(0, list.get(minimum));
list.set(minimum, temp);
}
}
sort(list.subList(1,list.size()));
}
我将其更改为接受List<Integer>
的参数(因为subList()
方法返回List
),然后摆脱了最后一个循环以及创建新对象的位置。
你还得改变
s.sort();
为:
s.sort(s.getarraylist());
输出:
ARRAY ELEMENTS
20
40
10
30
50
5
SORTED ELEMENTS
5
10
20
30
40
50
答案 2 :(得分:0)
我不确定我是否理解这个问题,但我创建了一个递归(和迭代)selectionSort和InsertionSort只是为了好玩,希望它有所帮助。
public class Sorts {
public static void swap(Comparable[] a, int i, int j) {
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void selectionSortItr(Comparable[] a, int n) {
for (int i = 0; i < n - 1; i++) {
int f = i;
for (int j = i + 1; j < n; j++) {
if (a[j].compareTo(a[f]) < 0)
f = j;
}
swap(a, i, f);
}
}
public static int select(Comparable[] a, int n, int j, int f) {
if (j >= n)
return f;
if (a[j].compareTo(a[f]) < 0)
f = j;
return select(a, n, j + 1, f);
}
public static void selectionSort(Comparable[] a, int n, int i) {
if (i < n - 1) {
swap(a, i, select(a, n, i + 1, i));
selectionSort(a, n, i + 1);
}
}
public static void insertionSortItr(Comparable[] a) {
for (int i = 1; i < a.length; i++) {
int j;
Comparable cur = a[i];
for (j = i; j > 0 && cur.compareTo(a[j - 1]) < 0; j--) {
a[j] = a[j - 1];
}
a[j] = cur;
}
}
public static void insertionSortInner(Comparable[] a, Comparable cur, int j) {
if (j > 0 && cur.compareTo(a[j - 1]) < 0) {
a[j] = a[j - 1];
insertionSortInner(a, cur, j - 1);
} else {
a[j] = cur;
}
}
public static void insertionSort(Comparable[] a, int i, int n) {
if (i < n) {
insertionSortInner(a, a[i], i);
insertionSort(a, i + 1, n);
}
}
public static void main(String[] args) {
Integer[] a = new Integer[10];
for (int i = 0; i < 10; i++)
a[i] = (int) (Math.random()*100);
selectionSort(a, 10, 0);
for (int i = 0; i < 10; i++)
System.out.println(a[i]);
}
}