java快速排序引發的StackOverflowError異常

寫在前面:這篇隨筆主要記錄一下遞歸調用引發的虛擬機棧溢出的狀況以及經過參數配置了虛擬機棧大小來使遞歸調用能夠順利執行。並無對涉及到的一些概念進行詳細的解釋(由於我本身目前對這些概念並非特別清楚),能夠用於參考的關鍵字:java

關鍵字:java虛擬機棧,棧溢出,棧幀算法


 

今天在對比快速排序與冒泡排序時,經過代碼分別實現了最簡單的快速排序與冒泡排序(從小到大排序),代碼以下:數組

 1 /**
 2  * 冒泡排序
 3  */
 4 
 5 public class BubbleSortDemo {
 6     public static void main(String[] args) {
 7         int[] nums = new int[100000];
 8         for (int i = nums.length - 1, j = 0; i >= 0; i--, j++) {
 9             nums[j] = i;
10         }
11         long start = System.currentTimeMillis();
12         bubbleSort(nums);
13         long end = System.currentTimeMillis();
14         System.out.println((end - start) + "ms");
15     }
16 
17     public static void bubbleSort(int[] nums) {
18         int swapCount = -1;
19         while (swapCount != 0) {
20             swapCount = 0;
21             for (int i = 0; i < nums.length - 1; i++) {
22                 int iItem = nums[i];
23                 int jItem = nums[i + 1];
24                 if (iItem > jItem) {
25                     swap(nums, i, i + 1);
26                     swapCount++;
27                 }
28             }
29         }
30     }
31 
32     /**
33      * 交換數組nums[]中i和j位置的兩個元素
34      */
35     public static void swap(int[] nums, int i, int j) {
36         int temp = nums[i];
37         nums[i] = nums[j];
38         nums[j] = temp;
39     }
40 }

 

 1 /**
 2  * 快速排序
 3  */
 4 
 5 public class QuickSortDemo {
 6     public static void quickSort(int[] nums, int leftIndex, int rightIndex) {
 7         if (nums.length <= 1 || leftIndex >= rightIndex) {
 8             return;
 9         }
10         
11         int pivot = nums[leftIndex];
12         int left = leftIndex;
13         int right = rightIndex;
14         
15         while (left < right) {
16             while (left < right && nums[right] >= pivot) {
17                 right --;
18             }
19             if (left < right) {
20                 nums[left] = nums[right];
21                 left ++;
22             }
23             while (left < right && nums[left] <= pivot) {
24                 left ++;
25             }
26             if (left < right) {
27                 nums[right] = nums[left];
28                 right --;
29             }
30         }
31         nums[left] = pivot;
32         quickSort(nums, leftIndex, left - 1);
33         quickSort(nums, left + 1, rightIndex);
34     }
35     
36     public static void quickSort(int[] nums) {
37         if (nums != null) {
38             quickSort(nums, 0, nums.length - 1);
39         }
40     }
41     
42     public static void main(String[] args) {
43         int[] nums = new int[100000];
44         for (int i = nums.length - 1, j = 0; i >= 0; i--, j++) {
45             nums[j] = i;
46         }
47         long start = System.currentTimeMillis();
48         quickSort(nums);
49         long end = System.currentTimeMillis();
50         System.out.println((end - start) + "ms");
51     }
52 
53 }

 

在它們的main函數中,我生成了length=100000的從大到小排列的有序數組對兩個排序算法進行測試,觀察它們的執行時間。函數

對於冒泡排序,對100000個有序數組進行排序,花費了12833ms。測試

對於快速排序,對100000個有序數組進行排序,由於快速排序採用了遞歸來實現,程序拋出了StackOverflowError異常,原本覺得是哪一個地方陷入了死循環致使的,後來通過排查,實際上是由於虛擬機棧溢出,函數調用的太深了。經過設置虛擬機參數-Xss10m,爲虛擬機棧分配了10M的內存,使這個算法能夠正常執行。最後,快速排序花費了4830ms。ui

相關文章
相關標籤/搜索