如何使用插入排序对ArrayList进行排序?

时间:2019-05-16 18:19:53

标签: java arraylist text-files insertion-sort

我有一个作业,我的老师要我们导入带有2043 Euromillions键的以下格式的文本文件:

1987 45 12 14 39 43 48 8 10
1981 23 12 18 22 29 45 10 12
1980 6 29 31 45 46 50 4 8
2018 19 2 4 16 19 50 6 12
1986 23 1 10 33 38 42 7 12
1986 40 18 23 26 27 36 7 12
...

我已将文件导入到ArrayList中,我需要使用插入排序按日期(第一个数字是年,下一个是星期)对键进行排序,格式如下:

{1987/45} |12|14|39|43|48| |8|10|
{1981/23} |12|18|22|29|45| |10|12|
...

关于如何按日期对键进行排序并将其存储在Array或ArrayList中的任何想法?

我已经将文件导入到ArrayList中,但是如果它是个好主意,则将其导入idk,我尝试对ArrayList进行排序,但没有成功。

private static ArrayList<String> ImportedKeys = new ArrayList<String>();

public static void importarChaves() {

String linha;

        int year,week,ball1,ball2,ball3,ball4,ball5,star1,star2;

        File file=new File("Documento/euromilhoes.txt");
        Scanner leitor=null;
        try {
            leitor = new Scanner(file);
        } catch (FileNotFoundException e) {
            System.out.println("File not found");
            e.printStackTrace();
        }
        int count = 0;
        while(leitor.hasNextLine()){

            linha=leitor.nextLine();
            // System.out.println(linha);

            Scanner lerString=new Scanner(linha);

            year=lerString.nextInt();
            week=lerString.nextInt();
            ball1=lerString.nextInt();
            ball2=lerString.nextInt();
            ball3=lerString.nextInt();
            ball4=lerString.nextInt();
            ball5=lerString.nextInt();
            star1=lerString.nextInt();
            star2=lerString.nextInt();

            ImportedKeys.add(linha);

            count++;
            lerString.close();


        }

1 个答案:

答案 0 :(得分:1)

几件事。首先,插入排序是一种非常特殊的排序类型,您可以在插入时进行排序。也就是说,在任何给定时间,都会对数组进行排序。添加第400个元素时,会将其插入正确的位置。

这就是我要做的。首先,我将从一个简短得多的示例文件开始,这样您的输出是合理的。 10行。

我将创建一个对象,该对象代表一行,但不是字符串,而是包含各个部分的对象。请记住,您无法进行字符串比较,因为第6周将在第11周之后进行排序。因此,您的对象可能包含数字年份,数字星期,然后是其他任何东西。

然后,我将执行此操作:我只需要编写一个输入方法即可读取文件,并生成新对象的(未排序的)数组。通过读取文件并输出结果进行测试。这将验证您的阅读是否正确。

那我会理解一些概念。

  1. 对一个空列表进行排序。
  2. 对包含1个项目的列表进行排序。
  3. 如果列表已排序,则可以对其进行二进制搜索。

什么是二进制搜索?

class MyArray extends ArrayList<MyObject> {
    public int insertionPoint(int year, int month {
         return insertionPoint(year, month, 0, length());
    }

    private int insertionPoint(int year, int month, int low, int high) {
        if (low >= high) {
             return low;
        }
        int mid = (low + high) / 2;
        MyObject obj = get(mid);
        if (obj.year < year || (obj.year == year && obj.month < month)) {
            return insertionPoint(year, month, low, mid);
        }
        return insertionPoint(year, month, mid+1, high);
    }
}

这是一个二进制搜索。这是一个非常重要的概念。您的列表已排序,这意味着您可以通过将列表分成两半来快速找到现有对象(或新对象应该到达的位置)。假设有2000个项目。您检查第1000个项目。如果您要搜索之前的位置(请参见if语句),那么。您只需要查看列表的前半部分。否则,您将查看下半部分。

有了插入点后,您只需在该点将NEW项目插入列表即可。这是一个插入列表。

注意:我不是在IDE中而是手动编写代码。可能并不完美。

总而言之,完成后,这应该少于100行代码。这样就足以定义您的新对象,再定义一个知道如何执行插入操作的排序列表,以及用于测试它的代码。

但是插入排序的窍门:

  1. 随时随地对数组进行排序
  2. 了解二进制搜索
  3. 您需要了解递归。我上面的第二种方法是高度递归的。它将列表分成越来越小的部分,直到弄清楚下一个项目应该去哪里。

那你做什么:

  1. 制作MyObject对象(或任何您称呼的对象)。
  2. int location = myList.insertLocation(object.year,object.week)
  3. 添加(位置,对象)