Java实现常见排序算法
常见的排序算法有冒泡排序、选择排序、插入排序、堆排序、归并排序、快速排序、希尔排序、基数排序、计数排序,下面通过Java实现这些排序
1、冒泡排序
package com.buaa; import java.util.Arrays; /** * @ProjectName SortingAlgorithm * @PackageName com.buaa * @ClassName BubbleSort * @Description 冒泡排序 * @Author 刘吉超 * @Date 2016-05-02 20:52:16 */ public class BubbleSort { /* * 时间复杂度为O(n2) */ public static void bubbleSort(int[] arr) { if (arr == null || arr.length < 2) { return; } for (int i = arr.length - 1; i >= 0; i--) { for (int j = 0; j < i; j++) { if (arr[j] > arr[j + 1]) { swap(arr, j, j + 1); } } } } // 元素交换 public static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; } // 生成数组 public static int[] generateArray(int len, int range) { if (len < 1) { return new int[0]; } int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int) (Math.random() * range); } return arr; } // 是否已经排序好 public static boolean isSorted(int[] arr) { if (arr == null || arr.length < 2) { return true; } for (int i = 1; i < arr.length; i++) { if (arr[i - 1] > arr[i]) { return false; } } return true; } public static void main(String[] args) { int len = 10; int range = 10; // 生成序列 int[] arr = generateArray(len, range); System.out.println("排序前:" + Arrays.toString(arr)); // 判断是否是有序的,如果无序,则进行排序 if(!isSorted(arr)){ bubbleSort(arr); } System.out.println("排序后:" + Arrays.toString(arr)); } }
2、选择排序
package com.buaa; import java.util.Arrays; /** * @ProjectName SortingAlgorithm * @PackageName com.buaa * @ClassName SelectSort * @Description 选择排序 * @Author 刘吉超 * @Date 2016-05-02 21:10:50 */ public class SelectSort { /* * 时间复杂度为O(n2) */ public static void selectSort(int[] arr) { if (arr == null || arr.length < 2) { return; } for(int i = arr.length - 1; i >= 0; i--){ int max = i; for(int j = 0;j < i;j++){ max = arr[j] > arr[max] ? j : max; } swap(arr, i, max); } } // 元素交换 public static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; } // 生成序列 public static int[] generateArray(int len, int range) { if (len < 1) { return null; } int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int) (Math.random() * range); } return arr; } // 判断序列是否有序 public static boolean isSorted(int[] arr) { if (arr == null || arr.length < 2) { return true; } for (int i = 1; i < arr.length; i++) { if (arr[i - 1] > arr[i]) { return false; } } return true; } public static void main(String[] args) { int len = 10; int range = 10; // 生成序列 int[] arr = generateArray(len, range); System.out.println("排序前:" + Arrays.toString(arr)); // 判断是否是有序的,如果无序,则进行排序 if(!isSorted(arr)){ selectSort(arr); } System.out.println("排序后:" + Arrays.toString(arr)); } }
3、插入排序
package com.buaa; import java.util.Arrays; /** * @ProjectName SortingAlgorithm * @PackageName com.buaa * @ClassName InsertionSort * @Description 插入排序 * @author 刘吉超 * @date 2016-03-05 20:11:48 */ public class InsertionSort { /* 时间复杂度 当数据正序时,执行效率最好,每次插入都不用移动前面的元素,时间复杂度为O(N)。 当数据反序时,执行效率最差,每次插入都要前面的元素后移,时间复杂度为O(N2)。 所以,数据越接近正序,直接插入排序的算法性能越好。 空间复杂度 由插入排序算法可知,我们在排序过程中,需要一个临时变量存储要插入的值,所以空间复杂度为1 。 算法稳定性 插入排序的过程中,不需要改变相等数值元素的位置,所以它是稳定的算法。 */ public static void insertionSort(int[] arr) { if (arr == null || arr.length < 2) { return; } for (int i = 1; i < arr.length; i++) { for (int j = i - 1; j >= 0; j--) { if (arr[j] > arr[j + 1]) { swap(arr,j,j+1); } } } } // 元素交换 public static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; } // 生成序列 public static int[] generateArray(int len, int range) { if (len < 1) { return new int[0]; } int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int) (Math.random() * range); } return arr; } // 判断序列是否有序 public static boolean isSorted(int[] arr) { if (arr == null || arr.length < 2) { return true; } for (int i = 1; i < arr.length; i++) { if (arr[i - 1] > arr[i]) { return false; } } return true; } public static void main(String[] args) { int len = 10; int range = 10; // 生成序列 int[] arr = generateArray(len, range); System.out.println("排序前:" + Arrays.toString(arr)); // 判断是否是有序的,如果无序,则进行排序 if (!isSorted(arr)) { insertionSort(arr); } System.out.println("排序后:" + Arrays.toString(arr)); } }
4、堆排序
package com.buaa; import java.util.Arrays; /** * @ProjectName SortingAlgorithm * @PackageName com.buaa * @ClassName HeapSort * @Description 堆排序 * @Author 刘吉超 * @Date 2016-05-03 22:34:47 */ public class HeapSort { // 堆排序 public static void heapSort(int[] arr){ // 数组长度 int length = arr.length; // 初始化堆 int[] heap = Arrays.copyOf(arr, length); // 对堆进行调整 for(int i = (length -1)/2; i >=0; i--){ process(heap,length,i); } int index = 0; // 输出堆 while(length > 0){ // 将排好序的元素弹出 arr[index++] = heap[0]; // 末尾元素添加到首部 heap[0] = heap[length-1]; // 总个数减一 length--; // 对堆进行调整 process(heap,length,0); } } /* * 对节点k进行调整 * h:堆数据;n:堆数据有效个数;k:待调整节点 */ public static void process(int[] h,int n,int k){ int k1 = 2*k+1; int k2 = 2*k+2; // 已经是叶子节点 if(k1 >= n && k2 >= n) return; // 左节点 int n1 = h[k1]; // 右节点 int n2 = k2 < n ? h[k2]:Integer.MAX_VALUE; // 已经符合堆的要求 if(h[k] <= n1 && h[k] < n2) return ; if(n1 < n2){ swap(h,k,k1); process(h,n,k1); }else { swap(h,k,k2); process(h,n,k2); } } // 元素交换 public static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; } // 生成序列 public static int[] generateArray(int len, int range) { if (len < 1) { return null; } int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int) (Math.random() * range); } return arr; } // 判断序列是否有序 public static boolean isSorted(int[] arr) { if (arr == null || arr.length < 2) { return true; } for (int i = 1; i < arr.length; i++) { if (arr[i - 1] > arr[i]) { return false; } } return true; } public static void main(String[] args) { int len = 10; int range = 10; // 生成序列 int[] arr = generateArray(len, range); System.out.println("排序前:" + Arrays.toString(arr)); // 判断是否是有序的,如果无序,则进行排序 if(!isSorted(arr)){ heapSort(arr); } System.out.print("排序后:" + Arrays.toString(arr)); } }
5、归并排序
package com.buaa; import java.util.Arrays; /** * @ProjectName SortingAlgorithm * @PackageName com.buaa * @ClassName MergeSort * @Description 归并排序 * @Author 刘吉超 * @Date 2016-05-02 21:53:54 */ public class MergeSort { // 归并排序 public static void mergeSort(int[] arr){ if(arr == null || arr.length < 2){ return ; } process(arr,0,arr.length - 1); } public static void process(int[] arr, int left, int right) { if (left == right) { return; } int mid = (left + right) / 2; // 左边 process(arr, left, mid); // 右边 process(arr, mid + 1, right); // 归并 merge(arr, left, mid, right); } public static void merge(int[] arr, int left, int mid, int right) { int[] help = new int[right - left + 1]; int l = left,r = mid + 1,index = 0; while (l <= mid && r <= right) { if (arr[l] <= arr[r]) { help[index++] = arr[l++]; } else { help[index++] = arr[r++]; } } while (l <= mid) { help[index++] = arr[l++]; } while (r <= right) { help[index++] = arr[r++]; } for (int i = 0; i < help.length; i++) { arr[left + i] = help[i]; } } // 生成序列 public static int[] generateArray(int len, int range) { if (len < 1) { return null; } int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int) (Math.random() * range); } return arr; } // 判断序列是否有序 public static boolean isSorted(int[] arr) { if (arr == null || arr.length < 2) { return true; } for (int i = 1; i < arr.length; i++) { if (arr[i - 1] > arr[i]) { return false; } } return true; } public static void main(String[] args) { int len = 10; int range = 10; // 生成序列 int[] arr = generateArray(len, range); System.out.println("排序前:" + Arrays.toString(arr)); // 判断是否是有序的,如果无序,则进行排序 if (!isSorted(arr)) { mergeSort(arr); } System.out.println("排序后:" + Arrays.toString(arr)); } }
6、快速排序
package com.buaa; import java.util.Arrays; /** * @ProjectName SortingAlgorithm * @PackageName com.buaa * @ClassName QuickSort * @Description 快速排序 * @Author 刘吉超 * @Date 2016-05-02 22:09:32 */ public class QuickSort { // 快速排序 public static void quickSort(int[] arr) { if (arr == null || arr.length < 2) { return; } process(arr, 0, arr.length - 1); } public static void process(int[] arr, int left, int right) { if (left < right) { int random = left + (int) (Math.random() * (right - left + 1)); swap(arr, random, right); int mid = partition(arr, left, right); // 左分区 process(arr, left, mid - 1); // 右分区 process(arr, mid + 1, right); } } public static int partition(int[] arr, int left, int right) { int pivot = left - 1; int index = left; while (index <= right) { if (arr[index] <= arr[right]) { swap(arr, ++pivot, index); } index++; } return pivot; } // 元素交换 public static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; } // 生成序列 public static int[] generateArray(int len, int range) { if (len < 1) { return null; } int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int) (Math.random() * range); } return arr; } // 判断序列是否有序 public static boolean isSorted(int[] arr) { if (arr == null || arr.length < 2) { return true; } for (int i = 1; i < arr.length; i++) { if (arr[i - 1] > arr[i]) { return false; } } return true; } public static void main(String[] args) { int len = 10; int range = 10; // 生成序列 int[] arr = generateArray(len, range); System.out.println("排序前:" + Arrays.toString(arr)); // 判断是否是有序的,如果无序,则进行排序 if(!isSorted(arr)){ quickSort(arr); } System.out.println("排序后:" + Arrays.toString(arr)); } }
7、希尔排序
package com.buaa; import java.util.Arrays; /** * @ProjectName SortingAlgorithm * @PackageName com.buaa * @ClassName ShellSort * @Description 希尔排序 * @author 刘吉超 * @date 2016-03-11 11:13:55 */ public class ShellSort { public static void shellSort(int[] arr) { if (arr == null || arr.length < 2) { return; } int feet = arr.length / 2; int index = 0; while (feet > 0) { for (int i = feet; i < arr.length; i++) { index = i; while (index >= feet) { if (arr[index - feet] > arr[index]) { swap(arr, index - feet, index); index -= feet; } else { break; } } } feet /= 2; } } // 元素交换 public static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; } // 生成序列 public static int[] generateArray(int len, int range) { if (len < 1) { return null; } int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int) (Math.random() * range); } return arr; } // 判断序列是否有序 public static boolean isSorted(int[] arr) { if (arr == null || arr.length < 2) { return true; } for (int i = 1; i < arr.length; i++) { if (arr[i - 1] > arr[i]) { return false; } } return true; } public static void main(String[] args) { int len = 10; int range = 10; // 生成序列 int[] arr = generateArray(len, range); System.out.println("排序前:" + Arrays.toString(arr)); // 判断是否是有序的,如果无序,则进行排序 if(!isSorted(arr)){ shellSort(arr); } System.out.println("排序后:" + Arrays.toString(arr)); } }
8、基数排序
package com.buaa; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; /** * @ProjectName SortingAlgorithm * @PackageName com.buaa * @ClassName RadixSort * @Description 基数排序 * @Author 刘吉超 * @Date 2016-05-02 22:19:31 */ public class RadixSort { public static void radixSort(int[] arr) { if (arr == null || arr.length < 2) { return; } // 负数特殊处理 int negNum = 0; for (int i = 0; i < arr.length; i++) { negNum += arr[i] < 0 ? 1 : 0; } // 负数 int[] negArr = new int[negNum]; // 正数 int[] posArr = new int[arr.length - negNum]; int negi = 0; int posi = 0; for (int i = 0; i < arr.length; i++) { if (arr[i] < 0) { negArr[negi++] = -arr[i]; } else { posArr[posi++] = arr[i]; } } // 负数排序 radixSortForPositive(negArr); // 正数排序 radixSortForPositive(posArr); int index = 0; for (int i = negArr.length - 1; i >= 0; i--) { arr[index++] = -negArr[i]; } for (int i = 0; i < posArr.length; i++) { arr[index++] = posArr[i]; } } // 排序 public static void radixSortForPositive(int[] arr) { if (arr == null || arr.length < 2) { return; } // 初始化 List<LinkedList<Integer>> qArr1 = new ArrayList<LinkedList<Integer>>(); List<LinkedList<Integer>> qArr2 = new ArrayList<LinkedList<Integer>>(); for (int i = 0; i < 10; i++) { qArr1.add(new LinkedList<Integer>()); qArr2.add(new LinkedList<Integer>()); } // 个位 for (int i = 0; i < arr.length; i++) { qArr1.get(arr[i] % 10).offer(arr[i]); } // 十位、百位、千位等 long radix = 10; // 用来做计数的,避免无效循环 int countFlag = 0; while (countFlag < arr.length && radix <= Integer.MAX_VALUE) { // 每次执行前,先重置该变量的值为0 countFlag = 0; for (int i = 0; i < 10; i++) { LinkedList<Integer> queue = qArr1.get(i); while (!queue.isEmpty()) { int value = queue.poll(); int radixValue = (int)(value / radix) % 10; qArr2.get(radixValue).offer(value); // 计数,避免无效循环 if(radixValue == 0){ countFlag++; } } } List<LinkedList<Integer>> temp = qArr1; qArr1 = qArr2; qArr2 = temp; radix *= 10; } // 弹出栈 int index = 0; for (int i = 0; i < 10; i++) { LinkedList<Integer> queue = qArr1.get(i); while (!queue.isEmpty()) { arr[index++] = queue.poll(); } } } // 生成序列 public static int[] generateArray(int len, int range) { if (len < 1) { return null; } int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int) (Math.random() * range); } return arr; } // 判断序列是否有序 public static boolean isSorted(int[] arr) { if (arr == null || arr.length < 2) { return true; } for (int i = 1; i < arr.length; i++) { if (arr[i - 1] > arr[i]) { return false; } } return true; } public static void main(String[] args) { int len = 10; int range = 100; // 生成序列 int[] arr = generateArray(len, range); System.out.println("排序前:" + Arrays.toString(arr)); // 判断是否是有序的,如果无序,则进行排序 if(!isSorted(arr)){ radixSort(arr); } System.out.println("排序后:" + Arrays.toString(arr)); } }
9、计数排序
package com.buaa; import java.util.Arrays; /** * @ProjectName SortingAlgorithm * @PackageName com.buaa * @ClassName CountSort * @Description 计数排序 * @Author 刘吉超 * @Date 2016-05-02 22:17:22 */ public class CountSort { // 计数排序 public static void countSort(int[] arr) { if (arr == null || arr.length < 2) { return; } // 最大值、最小值 int min = arr[0],max = arr[0]; for (int i = 1; i < arr.length; i++) { min = Math.min(arr[i], min); max = Math.max(arr[i], max); } // 定义数组 int[] countArr = new int[max - min + 1]; for (int i = 0; i < arr.length; i++) { countArr[arr[i] - min]++; } int index = 0; for (int i = 0; i < countArr.length; i++) { while (countArr[i]-- > 0) { arr[index++] = i + min; } } } // 元素交换 public static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; } // 生成序列 public static int[] generateArray(int len, int range) { if (len < 1) { return null; } int[] arr = new int[len]; for (int i = 0; i < len; i++) { arr[i] = (int) (Math.random() * range); } return arr; } // 判断序列是否有序 public static boolean isSorted(int[] arr) { if (arr == null || arr.length < 2) { return true; } for (int i = 1; i < arr.length; i++) { if (arr[i - 1] > arr[i]) { return false; } } return true; } public static void main(String[] args) { int len = 10; int range = 10; // 生成序列 int[] arr = generateArray(len, range); System.out.println("排序前:" + Arrays.toString(arr)); // 判断是否是有序的,如果无序,则进行排序 if(!isSorted(arr)){ countSort(arr); } System.out.println("排序后:" + Arrays.toString(arr)); } }