sort算法模板

算法模板

排序

冒泡:

public static void bubbleSort(int[] arr) {
    if (arr == null || arr.length < 2) {
        return;
    }
    for (int e = arr.length - 1; e > 0; e --) { // 0 ~ e范围上交换, 挨个冒泡
        for (int i = 0; i < e; i ++) {
            if (arr[i] > arr[i + 1]) {
                swap(arr, i, i + 1);
            }
        }
    }
}

选择:

public static void selectSort(int[] arr) {
    if (arr == null || arr.length < 2) {
        return;
    }
    for (int i = 0; i < arr.length; i ++) { // i ~ N - 1
        int minIndex = i;
        for (int j = i + 1; j < arr.length; j ++) { // i ~ N - 1上找最小值的下标
            minIndex = arr[j] < arr[minIndex] ? j : minIndex;
        }
        swap(arr, i , minIndex);
    }
}

插入:

public static void insertionSort(int[] arr) {
    if (arr == null || arr.length < 2) {
        return;
    }
    // 0 ~ 0已经有序了
    // 0 ~ i 想有序
    for (int i = 1; i < arr.length; i ++) {   // 使0 ~ i有序
        // 当前位置的数换到比前一个数小或者数组越界之后停止
        for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j --) {
            swap(arr, j, j + 1);
        }
    }
}

归并:

public static void mergeSort(int[] arr, int L, int M, int R) {
   // 辅助空间
   int[] help = new int[R - L + 1];
   int i = 0;
   // 左侧下标
   int p1 = L;
   // 右侧下标
   int p2 = M + 1;
   // p1和p2位置都不越界的时候,拷贝小点的数
   // while循环停止的时候,必有一个会越界
   while (p1 <= M && p2 <= R) {
       help[i ++] = arr[p1] <= arr[p2] ? arr[p1 ++] : arr[p2 ++];
   }
   // 两个while只会中一个
   // p1没越界,就全部拷贝p1到help中
   while (p1 <= M) {
       help[i ++] = arr[p1 ++];
   }
   // p2没越界,就全部拷贝p2到help中
   while (p2 <= R) {
       help[i ++] = arr[p2 ++];
   }
   for (i = 0; i < help.length; i ++) {
       arr[L + i] = help[i];
   }
}

/**
* 使左右两边有序
* @param arr
* @param L
* @param R
*/
public static void process(int[] arr, int L, int R) {
   if (L == R) {
       return;
   }

   int mid = L + ((R - L) >> 1);
   // 使左边有序
   process(arr, L, mid);
   // 使右边有序
   process(arr, mid + 1, R);
   // 整体merge
   mergeSort(arr, L, mid, R);
}

快排:

public static void process(int[] arr) {
   if (arr == null || arr.length < 2){
       return;
   }
   quickSort(arr, 0, arr.length - 1);
}

public static void quickSort(int[] arr, int L, int R) {
   if ( L < R) {
       swap(arr, L + (int) (Math.random() * (R - L + 1)), R);
       int[] p = partition(arr, L, R);
       quickSort(arr, L, p[0] - 1);
       quickSort(arr, p[1] + 1, R);
   }
}

public static int[] partition(int[] arr, int l, int r) {

   int less = l - 1;
   int more = r;

   while (l < more) {
       if (arr[l] < arr[r]) {
           swap(arr, ++ less, l++);
       } else if (arr[l] > arr[r]) {
           swap(arr, -- more, l);
       } else {
           l ++;
       }
   }
   swap(arr, more, r);
   return new int[] { less + 1, more };

}

堆排:

  • 先传入一个数组,将这个数组进行heapify(堆化),组成大根堆之后,将数组的第一个位置和最后一个位置进行交换,此时数组中的最大数找到了他的位置,将heapSize--,将最后一个数和heap断掉练习,反复执行这个过程直到所有的数字都找到了属于他的位置,排序完成
    
public static void heapSort(int[] arr) {
   if (arr == null || arr.length < 2) {
      return;
   }
   // 数组整体转为大根堆
   for (int i = 0; i < arr.length; i++) {
      heapInsert(arr, i);
   }
   int size = arr.length;
   // 0位置的数和堆上最后一个数进行交换
   swap(arr, 0, --size);
   // 如果heapSize大于0.代表堆上还有数字,一直进行交换
   while (size > 0) {
      heapify(arr, 0, size);
      swap(arr, 0, --size);
   }
}

public static void heapInsert(int[] arr, int index) {
   while (arr[index] > arr[(index - 1) / 2]) {
      swap(arr, index, (index - 1) /2);
      index = (index - 1)/2 ;
   }
}

// 堆化
public static void heapify(int[] arr, int index, int size) {
   int left = index * 2 + 1;
   while (left < size) {
      int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
      largest = arr[largest] > arr[index] ? largest : index;
      if (largest == index) {
         break;
      }
      swap(arr, largest, index);
      index = largest;
      left = index * 2 + 1;
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值