7种基本排序算法的Java实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7种基本排序算法的Java实现相关的知识,希望对你有一定的参考价值。

7种基本排序算法的Java实现

转自我的Github

 

以下为7种基本排序算法的Java实现,以及复杂度和稳定性的相关信息。

以下为代码片段,完整的代码见Sort.java

  • 插入排序
 1    /**
 2      * 直接插入排序
 3      * 不稳定
 4      * 时间复杂度:O(n^2)
 5      * 最差时间复杂度:O(n^2)
 6      * 空间复杂度:O(1)
 7      * 使用场景:大部分元素有序
 8      * @param elements
 9      * @param comparator
10      * @param <T>
11      */
12     public <T> void insertSort(T[] elements, Comparator<T> comparator) {
13         if (isInputInvalid(elements, comparator)) {
14             return;
15         }
16 
17         int length = elements.length;
18         for (int i = 1; i < length; i++) {
19             T current = elements[i];
20             int j;
21             for (j = i; j > 0; j--) {
22                 if (comparator.compare(elements[j - 1], current) > 0) {
23                     elements[j] = elements[j - 1];
24                 } else {
25                     break;
26                 }
27             }
28             elements[j] = current;
29         }
30     }

 

  • Shell排序
 1    /**
 2      * 希尔排序
 3      * 不稳定
 4      * 时间复杂度:O(nlogn)
 5      * 最差时间复杂度:O(n^s) 1<s<2
 6      * 空间复杂度:O(1)
 7      * 使用场景:元素小于5000
 8      * @param elements
 9      * @param comparator
10      * @param <T>
11      */
12     public <T> void shellSort(T[] elements, Comparator<T> comparator) {
13         if (isInputInvalid(elements, comparator)) {
14             return;
15         }
16         int length = elements.length;
17         for (int gap = length/2; gap >= 1; gap /= 2) {
18             for (int i = gap; i < length; i++) {
19                 T current = elements[i];
20                 int j;
21                 for (j = i; j >= gap; j = j - gap) {
22                     if (comparator.compare(elements[j - gap], current) > 0) {
23                         elements[j] = elements[j - gap];
24                     } else {
25                         break;
26                     }
27                 }
28                 elements[j] = current;
29             }
30 //            printArray(elements, "gap:" + gap);
31         }
32     }

 

  • 选择排序
 1    /**
 2      * 选择排序
 3      * 稳定
 4      * 时间复杂度:O(n^2)
 5      * 最差时间复杂度:O(n^2)
 6      * 空间复杂度:O(1)
 7      * 使用场景:n较少时
 8      * @param elements
 9      * @param comparator
10      * @param <T>
11      */
12     public <T> void selectSort(T[] elements, Comparator<T> comparator) {
13         if (isInputInvalid(elements, comparator)) {
14             return;
15         }
16 
17         int length = elements.length;
18         for (int i = 0; i < length - 1; i++) {
19             int min = i;
20             for (int j = i + 1; j < length; j++) {
21                 if (comparator.compare(elements[min], elements[j]) > 0) {
22                     min = j;
23                 }
24             }
25             if (min != i) {
26                 swap(elements, min, i);
27             }
28         }
29     }

 

  • 堆排序

优先级队列内部实现就是一个最小堆,这里就不自己实现heap了

 1    /**
 2      * 堆排序
 3      * 时间复杂度:O(nlogn)
 4      * 最差时间复杂度:O(nlogn)
 5      * 空间复杂度:O(n)
 6      * 使用场景:n较大时
 7      * @param elements
 8      * @param comparator
 9      * @param <T>
10      */
11     public <T> void heapSort(T[] elements, Comparator<T> comparator) {
12         if (isInputInvalid(elements, comparator)) {
13             return;
14         }
15 
16         PriorityQueue<T> heap = new PriorityQueue(elements.length, comparator);
17         for (T element : elements) {
18             heap.add(element);
19         }
20         for (int i = 0; i < elements.length; i++) {
21             elements[i] = heap.poll();
22         }
23     }

 

  • 冒泡排序
 1     /**
 2      * 冒泡排序
 3      * 稳定
 4      * 时间复杂度:O(n^2)
 5      * 空间复杂度:O(1)
 6      * 使用场景:n较小时
 7      * @param elements
 8      * @param comparator
 9      * @param <T>
10      */
11     public <T> void bubbleSort(T[] elements, Comparator<T> comparator) {
12         if (isInputInvalid(elements, comparator)) {
13             return;
14         }
15 
16         int length = elements.length;
17         for (int i = 1; i < length; i++) {
18             for (int j = length - 1; j >= i; j--) {
19                 if (comparator.compare(elements[j - 1], elements[j]) > 0) {
20                     swap(elements, j - 1, j);
21                 }
22             }
23         }
24     }

 

  • 快排
 1    /**
 2      * 快速排序
 3      * 不稳定
 4      * 时间复杂度:O(nlogn)
 5      * 最差时间复杂度:O(n^2)
 6      * 空间复杂度:O(logn)
 7      * 使用场景:由于是递归,不适合内存有限制的情况, n较大时
 8      * @param elements
 9      * @param comparator
10      * @param <T>
11      */
12     public <T> void quickSort(T[] elements, Comparator<T> comparator) {
13         if (isInputInvalid(elements, comparator)) {
14             return;
15         }
16         doQuickSort(elements, 0, elements.length - 1, comparator);
17     }
18 
19     private <T> void doQuickSort(T[] elements, int start, int end, Comparator<T> comparator) {
20         if (start >= end) {
21             return;
22         }
23         int pivot = partition(elements, start, end, comparator);
24         doQuickSort(elements, start, pivot - 1, comparator);
25         doQuickSort(elements, pivot + 1, end, comparator);
26     }
27 
28     private <T> int partition(T[] elements, int start, int end, Comparator<T> comparator) {
29         T pivot = elements[start];
30         int pivotIndex = start, forward = start, back = end;
31         while (forward < back) {
32             for (; comparator.compare(pivot, elements[forward]) >= 0 && forward < end; forward++) {}
33             for (; comparator.compare(pivot, elements[back]) <= 0 && back > start; back--) {}
34             if (forward < back) {
35                 swap(elements, forward++, back--);
36             }
37         }
38         swap(elements, back, pivotIndex);
39         return back;
40     }

 

  • 归并排序
 1    /**
 2      * 归并排序
 3      * 不稳定
 4      * 时间复杂度:O(nlogn)
 5      * 最差时间复杂度:O(nlogn)
 6      * 空间复杂度:O(n)
 7      * 使用场景:n较大时
 8      * @param elements
 9      * @param comparator
10      * @param <T>
11      */
12     public <T> void mergeSort(T[] elements, Comparator<T> comparator) {
13         if (isInputInvalid(elements, comparator)) {
14             return;
15         }
16 
17         Object[] aux = new Object[elements.length];
18         int start = 0, end = elements.length - 1;
19         doMergeSort(elements, start, end, comparator, aux);
20     }
21 
22     private <T> void doMergeSort(T[] elements, int start, int end, Comparator<T> comparator, Object[] aux) {
23         if (start >= end) {
24             return;
25         }
26         int mid = (start + end) / 2;
27         doMergeSort(elements, start, mid, comparator, aux);
28         doMergeSort(elements, mid + 1, end, comparator, aux);
29         merge(elements, start, mid, end, comparator, aux);
30     }
31 
32     private <T> void merge(T[] elements, int start, int mid, int end, Comparator<T> comparator, Object[] aux) {
33         int lb = start, rb = mid + 1, auxIndex = start;
34         while (lb <= mid && rb <= end) {
35             if (comparator.compare(elements[lb], elements[rb]) <= 0) {
36                 aux[auxIndex++] = elements[lb++];
37             } else {
38                 aux[auxIndex++] = elements[rb++];
39             }
40         }
41 
42         if (lb < mid + 1) {
43             while(lb <= mid) {
44                 aux[auxIndex++] = elements[lb++];
45             }
46         } else {
47             while(rb <= end) {
48                 aux[auxIndex++] = elements[rb++];
49             }
50         }
51 
52         for(int i = start; i <= end; i++) {
53             elements[i] = (T) aux[i];
54         }
55     }

 

  • 测试用方法
 1    public static void main(String[] args) {
 2         Integer[] elements = {3, 543, 54, 5, 6, 2, 67, 3, 65, 4};
 3 //        Integer[] elements = {0,0,0,0,0,0,0,0,0,0,0};
 4         printArray(elements, "OriginalArray");
 5 
 6         Sort sort = new Sort();
 7 
 8         Integer[] dupArray = dupArray(elements);
 9         sort.bubbleSort(dupArray, (o1, o2) -> o1 - o2);
10         printArray(dupArray, "BubbleSort");
11 
12         dupArray = dupArray(elements);
13         sort.insertSort(dupArray, (o1, o2) -> o1 - o2);
14         printArray(dupArray, "InsertSort");
15 
16         dupArray = dupArray(elements);
17         sort.selectSort(dupArray, (o1, o2) -> o1 - o2);
18         printArray(dupArray, "SelectSort");
19 
20         dupArray = dupArray(elements);
21         sort.heapSort(dupArray, (o1, o2) -> o1 - o2);
22         printArray(dupArray, "HeapSort");
23 
24         dupArray = dupArray(elements);
25         sort.quickSort(dupArray, (o1, o2) -> o1 - o2);
26         printArray(dupArray, "QuickSort");
27 
28         dupArray = dupArray(elements);
29         sort.shellSort(dupArray, (o1, o2) -> o1 - o2);
30         printArray(dupArray, "ShellSort");
31 
32         dupArray = dupArray(elements);
33         sort.mergeSort(dupArray, (o1, o2) -> o1 - o2);
34         printArray(dupArray, "MergeSort");
35     }
36 
37     private static <T> T[] dupArray(T[] array) {
38         return Arrays.copyOf(array, array.length);
39     }
40 
41     private static <T> void printArray(T[] array, String des) {
42         System.out.println(arrayToString(array) + " :" + des);
43     }
44 
45     public static <T> String arrayToString(T[] array) {
46         StringBuilder resultBuilder = new StringBuilder();
47         resultBuilder.append("{");
48         for (T item : array) {
49             resultBuilder.append(item).append(",");
50         }
51         resultBuilder.deleteCharAt(resultBuilder.length() - 1);
52         resultBuilder.append("}");
53         return resultBuilder.toString();
54     }

 

当然每种算法根据自身的缺陷都有可以改进的地方,可以结合不同的情况使用不同的排序算法,比如快排中使用三者取中的pivot选取方法,或者在快排在递归到比较小的元素划分的时候使用插入排序等等。
文中有不足之处还请大家批评指正。

以上是关于7种基本排序算法的Java实现的主要内容,如果未能解决你的问题,请参考以下文章

Java常用的八种排序算法与代码实现

Java常用的八种排序算法与代码实现

常见的七种排序算法(Java实现)

常见的七种排序算法(Java实现)

常见的七种排序算法(Java实现)

常见的七种排序算法(Java实现)