6种排序算法的简洁实现Java代码:冒泡、选择、插入、归并、快速、堆

jopen 10年前

注释写得已经非常详细了,有兴趣的可以瞧瞧。

源码&注释
package cn.fansunion.common.suanfa;    /**   * 排序工具类   *   * @author LeiWen@FansUnion.cn   *   */  public final class SortingUtils {        public static boolean debug = false;        // 不允许实例化      private SortingUtils() {        }        /**       * 冒泡排序:最容易理解的排序方法       */      public static void bubbleSort(int[] array) {          boolean needNextPass = true;            int length = array.length;          // 遍历N-1次,从第“2”个元素开始          for (int index = 1; index < length; index++) {              // 需要下一次排序              if (needNextPass) {                  needNextPass = false;                  // 遍历N-index次                  for (int i = 0; i < length - index; i++) {                      if (array[i] > array[i + 1]) {                          swap(array, i, i + 1);                          // 需要下一次排序                          needNextPass = true;                      }                  }              } else {                  // 已经有序了                  return;              }              debug(array);          }        }        /**       * 选择排序       */      public static void selectionSort(int[] array) {          for (int index = array.length - 1; index >= 1; index--) {                // 假设第0个是当前最大的              int curMaxValue = array[0];              int curMaxIndex = 0;                // 查找最大的元素 array[1..index]              for (int j = 1; j <= index; j++) {                  // 找到比当前值更大的元素                  if (curMaxValue < array[j]) {                      curMaxValue = array[j];                      curMaxIndex = j;                  }              }                // 交换元素              if (curMaxIndex != index) {                  array[curMaxIndex] = array[index];                  array[index] = curMaxValue;              }              debug(array);          }      }        /**       * 插入排序(容易理解,代码有一点难懂)       */      public static void insertionSort(int[] array) {          int length = array.length;          for (int index = 1; index < length; index++) {              // 插入 array[index]到一个已经有序的子列表 array[0..i-1],使得 array[0..i] 是有序的。              int curElement = array[index];              int k = -1;              // 从index的前面元素中,找到一个比array[index]大的元素              for (k = index - 1; k >= 0 && array[k] > curElement; k--) {                  array[k + 1] = array[k];              }              // 插入当前元素到 array[k+1]              array[k + 1] = curElement;              debug(array);          }      }        /**       * 快速排序:对所有元素排序。(递归实现,不容易理解)       */      public static void quickSort(int[] array) {          quickSort(array, 0, array.length - 1);      }        /**       * 快速排序:对某个区间的元素进行排序。       */      public static void quickSort(int[] array, int left, int right) {          int leftIndex = left;          int rightIndex = right;          // 选取中间的数作为主元          int middle = array[(leftIndex + rightIndex) / 2];            do {                // 在middle元素的左边,找到第1个比middle大的数              while (array[leftIndex] < middle && leftIndex < right) {                  // 如果左边的数小于中间的数,则一直向右移动                  // System.out.println(array[leftIndex] + "大于" + middle);                  leftIndex++;              }                // 在middle元素的右边,找到第1个比middle小的数              while (array[rightIndex] > middle && rightIndex > left) {                  // System.out.println(array[rightIndex] + "小于" + middle);                  rightIndex--;              }                // 将左边大的数和右边的小数交换              if (leftIndex <= rightIndex) {                  swap(array, leftIndex, rightIndex);                  leftIndex++;                  rightIndex--;              }              debug(array);          } while (leftIndex <= rightIndex);// 当两者交错时停止,每遍历一次,[...]            // 递归:对子区间的元素快速排序          if (leftIndex < right) {              quickSort(array, leftIndex, right);          }            // 递归:对子区间的元素快速排序          if (rightIndex > left) {              quickSort(array, left, rightIndex);          }      }        /**       * 交换数组中的2个元素       *       * @param array       *            数组       * @param i       *            第1个索引       * @param j       *            第2个索引       */      private static void swap(int[] array, int i, int j) {          if (array == null || array.length == 1) {              return;          }          int temp = array[i];          array[i] = array[j];          array[j] = temp;        }        /**       * 归并排序(递归实现,不容易理解)       */      public static void mergeSort(int[] array) {          int length = array.length;          // 长度大于1的数组,默认为“无序”;否则,默认为“有序”          if (length > 1) {              // 归并排序第一部分              int[] firstHalf = new int[length / 2];              System.arraycopy(array, 0, firstHalf, 0, length / 2);              mergeSort(firstHalf);                // 归并排序第二部分              int secondHalfLength = length - length / 2;              int[] secondHalf = new int[secondHalfLength];              System.arraycopy(array, length / 2, secondHalf, 0, secondHalfLength);              mergeSort(secondHalf);                // 合并第一部分和第二部分              int[] temp = merge(firstHalf, secondHalf);              System.arraycopy(temp, 0, array, 0, temp.length);          }      }        /**       * 把2个有序的数组合并成1个有序的数组       */      private static int[] merge(int[] array1, int[] array2) {          int length1 = array1.length;          int length2 = array2.length;          int[] resultArray = new int[length1 + length2];            int curIndex1 = 0; // array1的当前索引          int curIndex2 = 0; // array2的当前索引          int curIndexTemp = 0; // temp的当前索引            while (curIndex1 < length1 && curIndex2 < length2) {              if (array1[curIndex1] < array2[curIndex2]) {                  resultArray[curIndexTemp++] = array1[curIndex1++];              } else {                  resultArray[curIndexTemp++] = array2[curIndex2++];              }          }            while (curIndex1 < length1) {              resultArray[curIndexTemp++] = array1[curIndex1++];          }            while (curIndex2 < length2) {              resultArray[curIndexTemp++] = array2[curIndex2++];          }            return resultArray;      }        /**       * 打印数组       */      private static void print(int[] array) {          for (int i = 0; i < array.length; i++) {              System.out.print(array[i] + "  ");          }          System.out.println();      }        // 如果是debug模式,打印数组      private static void debug(int[] array) {          if (!debug) {              return;          }          System.out.print("[debug]");          for (int i = 0; i < array.length; i++) {              System.out.print(array[i] + "  ");          }          System.out.println();      }        private static void println(Object object) {          System.out.println(object);      }        /**       * 堆排序(太复杂,很难懂)       * <p>       * 堆的实现通过构造二叉堆(binary heap),实为二叉树的一种;由于其应用的普遍性,当不加限定时,均指该数据结构的这种实现。       * <p>       * 这种数据结构具有以下性质。 任意节点小于它的所有后裔,最小元在堆的根上(堆序性)。 堆总是一棵完全树。       *       * <p>       * 1.每次从数组添加一个元素来创建堆       * <p>       * 2.通过重复从堆中删除根       * <p>       * 3.重建堆来对数组排序。       */      public static void heapSort(int array[]) {          // 创建堆          for (int i = 1; i < array.length; i++) {              makeHeap(array, i);          }            // 删除根,重建堆,使得数组有序          for (int last = array.length - 1; last > 0;) {              swap(array, 0, last);              rebuildHeap(array, last--);              debug(array);          }      }        /**       * 假设[0..k-1]是一个堆,把array[k]加入到堆中       */      private static void makeHeap(int[] array, int k) {          int curIndex = k;            int middleIndex = (curIndex - 1) / 2;          while (curIndex > 0 && array[curIndex] > array[middleIndex]) {              swap(array, curIndex, middleIndex);              curIndex = middleIndex;          }      }        // 重建堆      private static void rebuildHeap(int[] array, int last) {          int curIndex = 0;          boolean isHeap = false;            while (!isHeap) {              int leftChildIndex = 2 * curIndex + 1;              int rightChildIndex = 2 * curIndex + 2;              int maxIndex = curIndex;                if (leftChildIndex <= last                      && array[maxIndex] < array[leftChildIndex]) {                  maxIndex = leftChildIndex;              }                if (rightChildIndex <= last                      && array[maxIndex] < array[rightChildIndex]) {                  maxIndex = rightChildIndex;              }                if (maxIndex != curIndex) {                  swap(array, curIndex, maxIndex);                  curIndex = maxIndex;              } else {                  isHeap = true;              }          }      }        /**       * 测试排序算法,比较直观;写单元测试也可,更严谨。       */      public static void main(String[] args) {          SortingUtils.debug = true;          testBubbleSort();          testSelectionSort();          testInsertionSort();          testQuickSort();          testMergeSort();          testHeapSort();        }        // 测试堆排序      private static void testHeapSort() {          println("堆排序:");          int[] heapSortArray = { 1, 13, 2, 4, 5, 7 };          quickSort(heapSortArray);          print(heapSortArray);      }        // 测试归并排序      private static void testMergeSort() {          println("归并排序:");          int[] mergeSortArray = { 1, 13, 2, 4, 5, 7 };          mergeSort(mergeSortArray);          print(mergeSortArray);      }        // 测试快速排序      private static void testQuickSort() {          println("快速排序:");          int[] quickSortArray = { 1, 13, 2, 4, 5, 7 };          quickSort(quickSortArray);          print(quickSortArray);      }        // 测试插入排序      private static void testInsertionSort() {          println("插入排序:");          int[] insertionSortArray = { 1, 13, 2, 4, 5, 7 };          insertionSort(insertionSortArray);          print(insertionSortArray);      }        // 测试选择排序      private static void testSelectionSort() {          println("选择排序:");          int[] selectionSortArray = { 1, 13, 2, 4, 5, 7 };          selectionSort(selectionSortArray);          print(selectionSortArray);      }        // 测试冒泡排序      private static void testBubbleSort() {          println("冒泡排序:");          int[] bubbleSortArray = { 1, 13, 2, 4, 5, 7 };          bubbleSort(bubbleSortArray);          print(bubbleSortArray);      }  }

运行结果

冒泡排序:
[debug]1  2  4  5  7  13  
[debug]1  2  4  5  7  13  
1  2  4  5  7  13  
选择排序:
[debug]1  7  2  4  5  13  
[debug]1  5  2  4  7  13  
[debug]1  4  2  5  7  13  
[debug]1  2  4  5  7  13  
[debug]1  2  4  5  7  13  
1  2  4  5  7  13  
插入排序:
[debug]1  13  2  4  5  7  
[debug]1  2  13  4  5  7  
[debug]1  2  4  13  5  7  
[debug]1  2  4  5  13  7  
[debug]1  2  4  5  7  13  
1  2  4  5  7  13  
快速排序:
[debug]1  2  13  4  5  7  
[debug]1  2  4  13  5  7  
[debug]1  2  4  5  13  7  
[debug]1  2  4  5  7  13  
[debug]1  2  4  5  7  13  
1  2  4  5  7  13  
归并排序:
1  2  4  5  7  13  
堆排序:
[debug]1  2  13  4  5  7  
[debug]1  2  4  13  5  7  
[debug]1  2  4  5  13  7  
[debug]1  2  4  5  7  13  
[debug]1  2  4  5  7  13  
1  2  4  5  7  13  

 

原文链接http://FansUnion.cn/articles/3349