归并排序

  1. import java.util.Arrays;
  2. public class Merge {
  3. public static void main(String[] args) {
  4. int[] a = {9,8,7,6,5,4,3,2,1,0};
  5. new Merge().sort(a,10);
  6. System.out.println(Arrays.toString(a));
  7. }
  8. public void sort(int[] a, int n) {
  9. mergesort(a,0, n-1);
  10. }
  11. public void mergesort(int[] a, int left, int right){
  12. if(left>=right)
  13. return;
  14. int mid = (right+left)/2;
  15. mergesort(a, left, mid);
  16. mergesort(a, mid+1, right);
  17. merge(a, left, mid, right);
  18. }
  19. //将a[left,mid] 和 a[mid+1, right]合并为a[left, right]
  20. public void merge(int[] a, int left, int mid, int right){
  21. int i = left;
  22. int j = mid+1;
  23. int t = 0;
  24. int[] temp = new int[right-left+1];
  25. while (i<=mid && j<=right){
  26. if(a[i]<=a[j]){
  27. temp[t++] = a[i++];
  28. }else {
  29. temp[t++] = a[j++];
  30. }
  31. }
  32. //判断哪个子数组还有元素
  33. int start = i;
  34. int end = mid;
  35. if(j<=right){
  36. start = j;
  37. end = right;
  38. }
  39. while(start <= end){
  40. temp[t++] = a[start++];
  41. }
  42. //将temp数组拷回a[left,right]
  43. //if (right - left + 1 >= 0) System.arraycopy(temp, 0, a, left + 0, right - left + 1);
  44. for (int k = 0; k <= right-left; k++) {
  45. a[left+k] = temp[k];
  46. }
  47. }
  48. }

堆排序

  1. /**
  2. * 堆排序
  3. */
  4. public class HeapSort {
  5. /**
  6. * 排序
  7. * 堆元素是从数组下标0开始
  8. * @param arr
  9. */
  10. public static void sort(int[] arr) {
  11. if (arr.length <= 1) {
  12. return;
  13. }
  14. // 1、建堆
  15. buildHeap(arr);
  16. // 2、排序
  17. int k = arr.length - 1;
  18. while (k > 0) {
  19. // 将堆顶元素(最大)与最后一个元素交换位置
  20. swap(arr, 0, k);
  21. // 将剩下元素重新堆化,堆顶元素变成最大元素
  22. heapify(arr, --k, 0);
  23. }
  24. }
  25. /**
  26. * 建堆
  27. *
  28. * @param arr
  29. */
  30. private static void buildHeap(int[] arr) {
  31. // (arr.length - 1) / 2 为最后一个叶子节点的父节点
  32. // 也就是最后一个非叶子节点,依次堆化直到根节点
  33. for (int i = (arr.length - 1) / 2; i >= 0; i--) {
  34. heapify(arr, arr.length - 1, i);
  35. }
  36. }
  37. /**
  38. * 堆化
  39. *
  40. * @param arr 要堆化的数组
  41. * @param n 最后堆元素下标
  42. * @param i 要堆化的元素下标
  43. */
  44. private static void heapify(int[] arr, int n, int i) {
  45. while (true) {
  46. // 最大值位置
  47. int maxPos = i;
  48. // 与左子节点(i * 2 + 1)比较,获取最大值位置
  49. if (i * 2 + 1 <= n && arr[i] < arr[i * 2 + 1]) {
  50. maxPos = i * 2 + 1;
  51. }
  52. // 最大值与右子节点(i * 2 + 2)比较,获取最大值位置
  53. if (i * 2 + 2 <= n && arr[maxPos] < arr[i * 2 + 2]) {
  54. maxPos = i * 2 + 2;
  55. }
  56. // 最大值是当前位置结束循环
  57. if (maxPos == i) {
  58. break;
  59. }
  60. // 与子节点交换位置
  61. swap(arr, i, maxPos);
  62. // 以交换后子节点位置接着往下查找
  63. i = maxPos;
  64. }
  65. }
  66. }

快速排序

  1. public class QuickSort {
  2. // 快速排序,a是数组,n表示数组的大小
  3. public static void quickSort(int[] a, int n) {
  4. quickSortInternally(a, 0, n-1);
  5. }
  6. // 快速排序递归函数,p,r为下标
  7. private static void quickSortInternally(int[] a, int p, int r) {
  8. if (p >= r) return;
  9. int q = partition(a, p, r); // 获取分区点
  10. quickSortInternally(a, p, q-1);
  11. quickSortInternally(a, q+1, r);
  12. }
  13. private static int partition(int[] a, int p, int r) {
  14. int pivot = a[r];
  15. int i = p;
  16. for(int j = p; j < r; ++j) {
  17. if (a[j] < pivot) {
  18. if (i == j) {
  19. ++i;
  20. } else {
  21. int tmp = a[i];
  22. a[i++] = a[j];
  23. a[j] = tmp;
  24. }
  25. }
  26. }
  27. int tmp = a[i];
  28. a[i] = a[r];
  29. a[r] = tmp;
  30. System.out.println("i=" + i);
  31. return i;
  32. }
  33. }