3.详解桶排序以及排序内容大总结 | 左程云算法笔记

317 阅读1分钟

堆排序

class Solution {


//   大根堆排序
    public void heapSort(int[] arr){
        if (arr == null || arr.length < 2) return;
//        将数组按大根堆排序,则 arr[0]是数组中最大的值
        for (int i = 0; i < arr.length; i++) {
            heapInsert(arr,i);
        }

        int size = arr.length;
//        把数组中最大的值放到末尾
        swap(arr,0,--size);
//        将数组的末尾不断删除,再堆化
        while (size > 0){
            heapify(arr,0,size);
            swap(arr,0,--size);
        }


    }

    public void heapInsert(int[] arr,int index){
//        找到父节点的下标
        int father = (index - 1) / 2;
//       只要子节点比父节点大就一直交换下去
        while (arr[index] > arr[father]){
            swap(arr,index,father);
            index = father;
            father = (index - 1) / 2;
        }
    }

    public void heapify(int[] arr,int index,int size){
//        找到index的左右孩子下标left right
        int left = 2 * index + 1;
        while (left < size){
            int right = left + 1;
//            largest为index left right三者最大的下标
            int largest = right < size && arr[right] > arr[left] ? right : left;
            largest = arr[largest] > arr[index] ? largest : index;
            if (largest == index){
                break;
            }
            swap(arr,largest,index);
            index = largest;
            left = 2 * index + 1;
        }



    }

    public void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] nums = new int[]{3,5,2,7,1,9,6};
        solution.heapSort(nums);
        System.out.println("1");

    }

}

堆排序扩展题目

已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序。

public class Code04_SortArrayDistanceLessK {

   public void sortedArrDistanceLessK(int[] arr, int k) {
      PriorityQueue<Integer> heap = new PriorityQueue<>();
      int index = 0;
      for (; index < Math.min(arr.length, k); index++) {
         heap.add(arr[index]);
      }
      int i = 0;
      for (; index < arr.length; i++, index++) {
         heap.add(arr[index]);
         arr[i] = heap.poll();
      }
      while (!heap.isEmpty()) {
         arr[i++] = heap.poll();
      }
   }
}

桶排序(基数排序)

class Solution {

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

//    算出数组中最大的位数 如[13,21,11,52,62,100] 最大位数为3
    public int maxbits(int[] arr){
        int max = Integer.MIN_VALUE;
        for (int i : arr) {
            max = Math.max(max,i);
        }
        int result = 0;
        while (max > 0){
            result++;
            max /=10;
        }
        return result;
    }

    public void radixSort(int[] arr, int begin, int end, int digit){
       final int radix = 10;
       //桶的长度与arr数组相同
       int[] bucket = new int[end - begin + 1];
        // 最大位数是3的话,就需要进行三次进桶出桶
       for (int d = 1; d <= digit; d++){
           
           int[] count = new int[radix];
           
           for (int i : arr) {
               count[getDigit(i,d)]++;
           }
           
           for (int i = 1; i < count.length; i++) {
               count[i] = count[i] + count[i - 1];
           }
           
           for (int j = end; j >= begin; j--){
               bucket[count[getDigit(arr[j],d)] - 1] = arr[j];
               count[getDigit(arr[j],d)]--;
           }
           
           for (int i = 0; i < bucket.length; i++) {
               arr[i] = bucket[i];
           }
       }
    }

//    取出d位上的数字 如 x=101,d=1是取出个位上的数字1,d=2是取出十位上的数字0
    public int getDigit(int x, int d){
        return  (x / (int) Math.pow(10,d - 1)) % 10;
    }
    

    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] nums = new int[]{17,13,25,100,72};
        solution.radixSort(nums);
        System.out.println("1");
    }

}