合并排序不起作用

时间:2016-04-26 04:14:30

标签: java eclipse sorting arraylist mergesort

我编写了一个程序,您可以使用3种不同的排序方法对ArrayList进行排序:bubble,merge和bogo(或愚蠢排序)。这是代码:

import java.util.*;
import java.io.*;
import java.lang.*;
import java.lang.IndexOutOfBoundsException;

public class Sorting {

    public static void bubbleSort(ArrayList<Integer> bubble) {
        int temp;
        if (bubble.size() > 1) {
            for (int i = 0; i < bubble.size(); i++) {
                for (int j = 0; j < bubble.size() - i - 1; j++) {
                    if (bubble.get(i).compareTo(bubble.get(i + 1)) > 0) {
                        temp = bubble.get(i);
                        bubble.set(i, bubble.get(i + 1));
                        bubble.set(i + 1, temp);
                    }
                }
            }
        }
    }

    public static ArrayList<Integer> mergeSort(ArrayList<Integer> merge) {
        if (merge.size() == 1) {
            return merge;
        } else {
            int halfway = merge.size() / 2;
            ArrayList<Integer> left = new ArrayList<Integer>(halfway);
            ArrayList<Integer> right = new ArrayList<Integer>(merge.size() - halfway);

            for (int i = 0; i < halfway; i++) {
                left.add(merge.get(i));
            }
            for (int i = halfway; i < merge.size(); i++) {
                right.add(merge.get(i));
            }

            left = mergeSort(left);
            right = mergeSort(right);

            ArrayList<Integer> newMerge = new ArrayList<Integer>(merge.size());

            int index1 = 0;
            int index2 = 0;

            for (int i = 0; i < merge.size(); i++) {
                if (index1 == left.size()) {
                    merge.set(i, right.get(index2));
                    index2++;
                } else if (index2 == right.size()) {
                    merge.set(i, left.get(index1));
                    index1++;
                } else {
                    if (left.get(index1) <= right.get(index2)) {
                        newMerge.set(i, left.get(index1));
                        index1++;
                    } else if (left.get(index1) >= right.get(index2)) {
                        newMerge.set(i, right.get(index2));
                        index2++;
                    }
                }
            }
            return newMerge;
        }
    }

    public static void bogoSort(ArrayList<Integer> bogo) {
        while (!isOrdered(bogo)) {
            Collections.shuffle(bogo);
        }
    }

    public static boolean isOrdered(ArrayList<Integer> order) {
        for (int i = 0; i < order.size(); i++) {
            if (order.get(i) > order.get(i + 1)) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        try {
            Scanner input = new Scanner(new File("random1.txt"));
            ArrayList<Integer> random = new ArrayList<Integer>();
            while (input.hasNextInt()) {
                random.add(input.nextInt());
            }
            input.close();

            System.out.println("Unsorted: " + random);

            long startTime = System.nanoTime();
            bubbleSort(random);
            long endTime = System.nanoTime();
            long duration = ((endTime - startTime) / 1000000);
            System.out.println("Sorted: " + random);
            System.out.println("Bubble sort took: " + duration + " milliseconds to sort.");
            System.out.println();

            long startTime2 = System.nanoTime();
            mergeSort(random);
            long endTime2 = System.nanoTime();
            long duration2 = ((endTime2 - startTime2) / 1000000);
            System.out.println("Sorted: " + random);
            System.out.println("Merge sort took: " + duration2 + " milliseconds to sort.");
            System.out.println();

            long startTime3 = System.nanoTime();
            bogoSort(random);
            long endTime3 = System.nanoTime();
            long duration3 = ((endTime3 - startTime3) / 1000000);
            System.out.println("Sorted: " + random);
            System.out.println("Bogo sort took: " + duration3 + " milliseconds to sort.");
            System.out.println();
        } catch (FileNotFoundException e) {
            System.out.println("File is not found.");
            System.exit(1);
        }
    }
}

当我运行程序时,未排序的ArrayList和冒泡排序方法出现了,但是我的Merge Sort方法收到错误,该方法声明我在第38,57和38行有一个IndexOutOfBoundsException。我正确地做了算法,但我不知道为什么我收到错误。这背后的任何推理?

3 个答案:

答案 0 :(得分:1)

更正代码

set()

精化

mergeSort()

的问题

当您开始合并左右子列表时,会出现此问题。请注意,在合并过程中,您可以在newMergemerge列表中调用newMerge方法。这不是你想要的。在&#34; merge&#34; -loop中,您可以尝试在i列表为空时或newMerge大于其大小时将值设置为merge列表。这就是你得到错误的原因。由于您的其他类似乎对传入的原始列表进行排序(而不是创建副本,排序和返回副本),我可以假设您的合并排序旨在执行相同操作。如果是这样的话,实际上根本不需要i == order.size() - 1列表,因为我们可以写入原始的i == order.size()列表。这种变化可以在上面的代码中看到。

isOrdered()

的问题

这里的小问题。你应该在i == order.size() - 1时终止你的循环,而不是在order.get(i + 1)时。否则,当<script type="text/javascript"> var oTable; $(document).ready(function() { oTable = $('#userListTable').dataTable( { "iDisplayLength": 25, "aLengthMenu": [5,10,25,50,100], "aoColumns": [ { "bSortable": false }, null, null, null, null, null, null, null, null, { "bSortable": false } ] }); oTable.fnSort( [ [1,'asc'] ] ); }); function removeUser() { var ids = ''; $("input:checked", oTable.fnGetNodes()).each(function(){ if (ids == '') { ids += $(this).val(); }else{ ids += ','+$(this).val(); } }); var url = "<?php echo base_url(); ?>Admin/userRemove/"; var form = $('<form action="' + url + '" method="post">' + '<input type="text" name="ids" value="' + ids + '" />' + '</form>'); console.log(form); $('body').append(form); if (ids != '') { form.submit(); }else{ alert('Select user to remove'); } } </script> //some codes here <button type="button" data-hover="tooltip" onclick="removeUser()" title="Delete Selected" class="btn btn-default"> <i class="fa fa-eraser"></i> </button> &nbsp;&nbsp;&nbsp; <button type="button" data-hover="tooltip" title="Add New User" class="btn btn-default"> <div class="panel-header" data-toggle="modal" data-target="#myModal"> <i class="fa fa-user-plus fa-1x"></i> </div> </button> // #myModal codes here <script type="text/javascript"> $(document).ready(function(){ $('.edit-row').live('click',function(){ var me = $(this); var editModal = $('#myModalEdit'); editModal.find('#userID').val(me.attr('data-userID')); editModal.find('#userName').val(me.attr('data-userName')); editModal.find('#userFullName').val(me.attr('data-userFullName')); editModal.find('#userPass').val(me.attr('data-userPass')); editModal.find('#userEmail').val(me.attr('data-userEmail')); $('#myModalEdit').modal('show'); }); }); </script> //#myModalEdit codes here <table id="userListTable" class="table table-hover table-striped table-bordered" > <thead> <tr> <th><center><strong>#</strong></center></th> <th><h4><strong>USER ID</strong></h4></th> <th><h4><strong>FULL NAME</strong></h4></th> <th><h4><strong>USERNAME</strong></h4></th> <th><h4><strong>EMAIL</strong></h4></th> </tr> </thead> <tbody> <?php if(!empty($data_user)): foreach($data_user as $row) { echo '<tr> <td class="text-center"> <input type="checkbox" name="selectAction" value="'.$row->userID.'" unchecked> </td>'; echo '<td>'.$row->userID.'</td>'; ?> <td><a class="edit-row" href="javascript:" data-userID="<?php echo $row->userID; ?>" data-userFullName="<?php echo $row->userFullName; ?>" data-userName="<?php echo $row->userName; ?>" data-userEmail="<?php echo $row->userEmail; ?>" > <?php echo $row->userFullName; ?> </a> </td> <?php echo '<td>'.$row->userName.'</td>'; echo '<td>'.$row->userEmail.'</td>'; echo '</tr>'; } endif; ?> </tbody> </thead> </table> // other codes 时,public function userRemove() { $ids = $this->input->post('ids'); if (!empty($ids)) { $this->db->where('userID IN (' . $this->input->post('ids') . ')') -> delete('user_tbl', $data); } redirect('userlist', 'refresh'); } 将尝试检索列表中不存在的元素(即超出范围)。

答案 1 :(得分:1)

要列表,如果索引大于该大小,则无法在特定索引处添加或设置元素。查看文档here。您可以将空值添加到List(newMerge)以解决此问题,或者只是将元素添加到newMerge列表中。我以后更喜欢。其他IndexOutOfBoundsException例外与此相关。

答案 2 :(得分:0)

  

我正确地做了算法,但我不知道为什么我收到错误。

显然,你没有正确地完成算法,或者你不会得到异常。 ; - )

您正在致电:

merge.set(i, right.get(index2));

merge.set(i, left.get(index1));

正在修改原始列表,而不是从newMerge返回的新创建的mergeSort列表。调用者期望返回的列表具有与传递的元素一样多的元素,但是(因为它永远不会被修改)它实际上具有零,这导致调用者中的异常。

使用newMerge作为set来电的目标,并使用add而不是尝试设置特定索引。