【问题标题】:Bubble Sort throws exception冒泡排序抛出异常
【发布时间】:2017-07-04 22:51:21
【问题描述】:

我正在为类编写一个程序来展示编码冒泡排序的能力。我已经为此工作了几天,似乎无法得到它。至少现在它可以编译,但会引发异常。
我评论了我遇到问题的部分,即数组中元素的实际交换。

该程序应该生成一个由 20 个随机整数组成的数组,然后使用冒泡排序对它们进行排序,并在执行过程中打印出每个通道,直到完成。

import java.util.*;


public class BubbleSorting {


public static void bubbleSort(ArrayList<Integer> arr) {
  int n = arr.size();
  int temp = 0;

  for (int i = 0; i < n; i++) {

   //this is the chunk of code that I am having problems with
     for (int j = i; j < (n-1); j++) {
        if (arr.get(n-1) < arr.get(j))
           temp = arr.get(j-1);
           arr.set(j-1, arr.get(j));
           arr.set(j, temp);
     }

   }
 }

private static void printOut(int pass, ArrayList<Integer> array) {
  System.out.print("Pass " + pass + ": ");
  for (int i = 0; i < array.size() - 1; i++) {
     System.out.print(array.get(i) + ", ");
  }

  System.out.print(array.get(array.size() - 1) + "."); 
  System.out.println();


}


public static void main(String[] args) {
  ArrayList<Integer> array = new ArrayList<Integer>();
  Scanner sc = new Scanner(System.in); 
  String userInput = ""; 
  boolean endLoop = false;

  do{
     try{

        for (int i = 0; i < 20; i++) {
           int element = (int)(1000.0 * Math.random());
           array.add(element);
        }
        System.out.print("\nUnsorted Array: ");

                //Displays the unsorted ArrayList
        for (int i = 0; i < array.size() - 1; i++) {
           System.out.print(array.get(i) + ", ");
        }

        System.out.print(array.get(array.size() - 1) + "."); 
        System.out.println();
        bubbleSort(array);
     }
     catch (IndexOutOfBoundsException e) {
        System.out.println("\nThere is an out of bounds error in the ArrayList.");
     }



     System.out.print("\nEnter Y to continue or N to quit: ");
        userInput = sc.nextLine();

     if (userInput.equalsIgnoreCase("Y")) {
        endLoop = false;

     }
     else if (userInput.equalsIgnoreCase("N")) {
        endLoop = true;
     }

     else { 
        System.out.println("\nYou did not enter Y or N.");
        System.out.println("Please try again.");
     }

    }while(endLoop == false);


   }
}

【问题讨论】:

  • 有什么例外?
  • 您是否尝试过使用调试器?还是手动遵循您的代码?例如,当您需要在 i = j = 0 时交换条目时会发生什么?
  • 当 i = 0 且 j = 0 时,您会得到 index = -1,即索引超出范围。因为你的 ji 开始。
  • 它会抛出一个异常,但我不会费心告诉你它是什么......

标签: java arrays sorting bubble-sort


【解决方案1】:

试试下面的代码:

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

您犯了 2 个错误...首先是在第一个 for 循环中使用 for(int j = 1; j &lt; (list.size() -i); j++) 而您编写了 int j=i,其次是您没有覆盖 if 循环条件中的 {} 括号。干杯

【讨论】:

    【解决方案2】:

    您可能对冒泡排序的工作原理存在误解。这是一个冒泡排序如何工作的示例(取自this link

    Let us take the array of numbers "5 1 4 2 8", and sort the array from lowest
    number to greatest number using bubble sort. In each step, elements written
    in bold are being compared. Three passes will be required.
    
    First Pass
    ( 5 1 4 2 8 ) ( 1 5 4 2 8 ), Here, algorithm 
    compares the first two elements, and swaps since 5 > 1.
    ( 1 5 4 2 8 ) ( 1 4 5 2 8 ), Swap since 5 > 4
    ( 1 4 5 2 8 ) ( 1 4 2 5 8 ), Swap since 5 > 2
    ( 1 4 2 5 8 ) ( 1 4 2 5 8 ), Now, since these elements are already in order
    (8 > 5), algorithm does not swap them.
    
    Second Pass
    ( 1 4 2 5 8 ) ( 1 4 2 5 8 )
    ( 1 4 2 5 8 ) ( 1 2 4 5 8 ), Swap since 4 > 2
    ( 1 2 4 5 8 ) ( 1 2 4 5 8 )
    ( 1 2 4 5 8 ) ( 1 2 4 5 8 )
    Now, the array is already sorted, but the algorithm does not know if it is
    completed. The algorithm needs one whole pass without any swap to know it is
    sorted.
    
    Third Pass
    ( 1 2 4 5 8 ) ( 1 2 4 5 8 )
    ( 1 2 4 5 8 ) ( 1 2 4 5 8 )
    ( 1 2 4 5 8 ) ( 1 2 4 5 8 )
    ( 1 2 4 5 8 ) ( 1 2 4 5 8 )
    

    现在,将这种思路与您的代码进行比较:

    for (int i = 0; i < n; i++) {
    
       //this is the chunk of code that I am having problems with
         for (int j = i; j < (n-1); j++) {
            if (arr.get(n-1) < arr.get(j))
               temp = arr.get(j-1);
               arr.set(j-1, arr.get(j));
               arr.set(j, temp);
         }
    
    }
    

    现在,如果您使用示例中的数组 (5 1 4 2 8) 并将其插入代码中,它将最终将 8 与每个给定数字进行比较,并且由于 8 已经是最大的,因此 if 语句永远是假的;不会发生排序。相反,一次比较两个相邻的索引并使用布尔值来指示是否发生了交换。鉴于这种功能,排序将继续将最大数字交换到数组的末尾。所以,一旦没有交换,你就知道数组已经排序了。因此,您希望内部循环仅上升到已排序的部分,而不是进一步。如果比较排序后的值,排序将提前结束。尝试使用这种思维方式并将其应用到您的代码中。

    【讨论】:

      【解决方案3】:

      男孩,你错过了 if 语句中的括号。

      //this is the chunk of code that I am having problems with
                      for (int j = i; j < (n - 1); j++) {
                          if (arr.get(n - 1) < arr.get(j)) {//<------here this one
                              temp = arr.get(j - 1);
                              arr.set(j - 1, arr.get(j));
                              arr.set(j, temp);
                          }//<----this too
                      }
      

      如果不加括号,则只考虑 if 后面的第一条语句。

      【讨论】:

      • 仍然不会排序...这只会避免 indexoutofbondsexception 但不会排序..在 for 循环中它的 int j=1 而不是 j=i...
      猜你喜欢
      • 1970-01-01
      • 2016-02-18
      • 1970-01-01
      • 2023-01-14
      • 2013-10-09
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多