递归选择在Java中排序

时间:2018-06-16 20:14:02

标签: java sorting recursion arraylist selection-sort

我需要实现此算法,在每次递归调用时创建一个新的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);
    }

}
}

3 个答案:

答案 0 :(得分:4)

你的算法实际上有两个错误,它们一起导致观察到的输出。

第一个错误是在for - 循环中确定最小元素:

for ( int j = 1; j < arr.size()-1; j++ ) { ...

您过早终止一个元素,即从不考虑最后一个元素。因此,在第一次迭代之后,5ArrayList中的最后一个元素。实际上,它是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)。

对您的代码的一些评论:

答案 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]);
    }
}