【经典代码块系列】排序算法

//都是哪些代码需要背下来呢?
//首先是经典的排序和搜索算法 以及各种经典的算法
//然后是在题型技巧讲解中明确要求背诵的算法或者代码块(这个工作量还挺大,要过一遍 记下来 然后背诵)
//最后是一些常见题型的背诵 比如reverse/palindrome/BFS/DFS 这个就是自己看着 觉得有价值就背等等

//首先是排序算法及其优化算法
public class BubbleSort {

    private static void bubbleSort(int[] nums){
        for (int i = 0; i < nums.length-1; i++) { //i控制每次的边界条件,i层数为length-1
            for (int j = nums.length-1; j > i; j--) { //j与j-1构成了指针,j每次都从nums.length-1开始,比如有五个元素的数组,每次都是先[4]和[3]比较
                if (nums[j] < nums[j-1]){
                    int temp = nums[j];
                    nums[j] = nums[j-1];
                    nums[j-1] = temp; //从后往前遍历,每次j的结束条件是到达I边界,因为每一次都是最前面的被排好
                }
            }

        }
    }
    private static void bubbleSortBest(int[] nums){
        boolean flag = false;
        for (int i = 0; i < nums.length-1; i++) { //i控制每次的边界条件,i层数为length-1
            flag = false;
            for (int j = nums.length-1; j > i; j--) { //j与j-1构成了指针,j每次都从nums.length-1开始,比如有五个元素的数组,每次都是先[4]和[3]比较
                if (nums[j] < nums[j-1]){
                    int temp = nums[j];
                    nums[j] = nums[j-1];
                    nums[j-1] = temp; //从后往前遍历,每次j的结束条件是到达I边界,因为每一次都是最前面的被排好
                    flag = true;//只要调用过这个内层的for循环,就要改变其boolean值
                }
            }
            if(!flag) {
                break;//只要没有改变过flag的值,即没有执行过调换,就直接break
            }

        }
    }
    public static void main(String[] args){
        int[] nums = new int[]{5,2,9,4,7,6,1,3,8};
        bubbleSortBest(nums);
    }
}


import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * n代表 待排序的数据 m指桶的数量
 * 最好 n
 * 最坏 无意义
 * 平均 n*(logn ~ logm)
 * 稳定
 */

public class BucketSort {

    public static void bucketSort(int[] nums) {
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            max = Math.max(max, nums[i]);
            min = Math.min(min, nums[i]);
        }

        int bucketNum = (max - min) / nums.length + 1;
        System.out.println("max "+max+" min "+min+" bucketNum "+bucketNum);
        List<List<Integer>> bucket = new ArrayList<>();
        for (int i = 0; i < bucketNum; i++) {
            bucket.add(new ArrayList<>()); //对所有的桶进行初始化
        }

        for (int i = 0; i < nums.length; i++) {
            int num = (nums[i] - min) / nums.length; //定位出该数应该放入哪个桶里面
            bucket.get(num).add(nums[i]); //将之放入
        }

        for (int i = 0; i < bucket.size(); i++) {
            Collections.sort(bucket.get(i)); //调用java自带的collections 库进行桶内部排序
        }

        System.out.println(bucket.toString());
    }

    public static void main(String[] args) {
        int[] nums = new int[]{5,2,9,4,7,6,1,3,8};
        bucketSort(nums);
    }
}


import java.util.Arrays;

/**
 * 最好 n
 * 最坏 就是想节省时间
 * 平均 n+k
 * 空间复杂度 k
 * 稳定
 */
// 其思想是用空间换时间 属于非比较排序
public class CountSort {

    public static void countSort(int[] nums) {
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; i++) {
            max = Math.max(max, nums[i]);
        }

        int[] count = new int[max+1];
        for (int i = 0; i < nums.length; i++) {
            count[nums[i]] = count[nums[i]] + 1;
        }

        System.out.println(Arrays.toString(count));
        int index = 0;
        for (int i = 0; i < max; i++) {
            for (int j = 0; j < count[i]; j++) {
                nums[index++] = i;
            }
        }
        System.out.println(Arrays.toString(nums));
    }

    public static void main(String[] args) {
        int[] nums = new int[]{5,2,9,4,7,6,1,3,8,20};
        countSort(nums);
    }
}



public class InsertSort {
    /**
     * 最好 n
     * 最坏 n2
     * 平均 n2
     * 稳定
     * @param nums
     */

    public static void insertSort(int[] nums) {
        int temp;
        for (int i = 0; i < nums.length-1; i++) {
            for (int j = i+1; j > 0; j--) {
                if (nums[j] < nums[j-1]){
                    temp = nums[j-1];
                    nums[j-1] = nums[j];
                    nums[j] = temp;
                } else {
                    break;
                }
            }
        }
    }

    public static void insertBinarySort(int[] nums) { //此方法是采用二分查找方式对之前的插入排序进行优化
        int temp;
        int low;
        int high;
        int mid;
        for (int i = 0; i < nums.length-1; i++) {
            temp = nums[i+1];
            low = 0;
            high = i;
            while(low <= high) {
                mid = (low + high) /2; //可能会溢出哦
                if (nums[mid] < temp) {
                    low = mid + 1;
                } else {
                    high = mid - 1;
                }
            }
            for (int j = 0; j > high ; j--) {
                nums[j+1] = nums[j]; //此for循环的目的是进行批量移位操作
            }

        }
    }
    public static void main(String[] args) {
        int[] nums = new int[]{5,2,9,4,7,6,1,3,8};
        insertSort(nums);
    }
}
// 加入了二分查找优化之后,最好:nlogn,最坏和平均都是n2

import java.util.Arrays;

public class MergeSort {
    /**
     * 最好 nlogn
     * 最坏 nlogn
     * 平均 nlogn
     * 空间复杂度: n
     * 稳定
     * @param nums
     * @param low
     * @param high
     * @return
     */

    public static int[] mergeSort(int[] nums, int low, int high) {
        int mid = (low + high)/2;
        if (low < high) {
            mergeSort(nums, low, mid);
            mergeSort(nums, mid+1, high);
            merge(nums, low, mid, high);
        }
        return nums;
    }

    public static void merge(int[] nums, int low, int mid, int high) {
        int[] temp = new int[high - low+1];
        int i = low;
        int j = mid + 1;
        int k = 0;
        while (i <= mid && j <= high) {
            if (nums[i] < nums[j]) {
                temp[k++] = nums[i++];
            } else {
                temp[k++] = nums[j++];
            }
        }
        while (i <= mid) {
            temp[k++] = nums[i++];
        }
        while (j <= high) {
            temp[k++] = nums[j++];
        }
        for (int l = 0; l < temp.length; l++) {
            nums[l + low] = temp[l];
        }
        System.out.println("当前排序结果: "+ Arrays.toString(temp));
    }
    public static void main(String[] args) {
        int[] nums = new int[]{5,2,9,4,7,6,1,3,8};
        mergeSort(nums, 0, nums.length-1);
    }
}


import java.util.Arrays;

 /**
 * 利用了pivoting elements,每遍历一次只能确定pivoting elements的位置
  * 最好 nlogn
  * 最坏 n2
  * 平均 nlogn
  * 空间复杂度 logn~n
  * 不稳定
 */
public class QuickSort {

    public static void  quickSort(int[] nums, int left, int right) {
        if (left < right) {
            int pivot = partition(nums, left, right);
            quickSort(nums, left, pivot -1);
            quickSort(nums, pivot + 1, right);
        }
    }

    public static int partition(int[] nums, int left, int right) { //返回当前pivot element的
        int pivotIndex = left;
        int pivot = nums[pivotIndex];
        int l = left + 1;
        int r = right;
        System.out.println("pivot: "+pivot+ Arrays.toString(nums));
        while (l <= r) {
            if (nums[l] > pivot && nums[r] < pivot) {
                swap(nums, l++, r--);
            }
            if (nums[l] <= pivot) l++;
            if (nums[r] >= pivot) r--;
            System.out.println("当前结果"+Arrays.toString(nums));
        }
        swap(nums, pivotIndex, r);
        System.out.println("此轮结束"+Arrays.toString(nums));
        return r;
    }

    public static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

     public static void main(String[] args) {
         int[] nums = new int[]{5,2,9,4,7,6,1,3,8};
         quickSort(nums, 0, nums.length-1);
     }
}


/**
 * 时间复杂度
 * 最好 O(n)
 * 最坏 n2
 * 平均 n2
 * 属于不稳定的排序算法
 */
public class SelectSort {

    public  static void selectSort(int[] nums) {
        for (int i = 0; i < nums.length - 1; i++) {
            int minIndex = i;
            for (int j = i+1; j < nums.length; j++) {
                if (nums[j] < nums[minIndex]) {
                    minIndex = j;
                }
            }
            if (minIndex != i) {
                int temp = nums[i];
                nums[i] = nums[minIndex];
                nums[minIndex] = temp;
            }
        }
    }
}


public class SortStabilization {
    /**
     * 稳定的排序
     * @param products
     */

    private static void bubbleSort(Product[] products){
        for (int i = 0; i < products.length-1; i++) { //i控制每次的边界条件,i层数为length-1
            for (int j = products.length-1; j > i; j--) { //j与j-1构成了指针,j每次都从nums.length-1开始,比如有五个元素的数组,每次都是先[4]和[3]比较
                if (products[j].getPrice() < products[j-1].getPrice()){
                    Product temp = products[j];
                    products[j] = products[j-1];
                    products[j-1] = temp; //从后往前遍历,每次j的结束条件是到达I边界,因为每一次都是最前面的被排好
                }
            }

        }
        for (int i = 0; i < products.length-1; i++) { //i控制每次的边界条件,i层数为length-1
            for (int j = products.length-1; j > i; j--) { //j与j-1构成了指针,j每次都从nums.length-1开始,比如有五个元素的数组,每次都是先[4]和[3]比较
                if (products[j].getSale() < products[j-1].getSale()){
                    Product temp = products[j];
                    products[j] = products[j-1];
                    products[j-1] = temp; //从后往前遍历,每次j的结束条件是到达I边界,因为每一次都是最前面的被排好
                }
            }

        }
    }

    /**
     * 不稳定的排序
     * @param products
     */
    private static void bubbleSort2(Product[] products){
        for (int i = 0; i < products.length-1; i++) { //i控制每次的边界条件,i层数为length-1
            for (int j = products.length-1; j > i; j--) { //j与j-1构成了指针,j每次都从nums.length-1开始,比如有五个元素的数组,每次都是先[4]和[3]比较
                if (products[j-1].getPrice() >= products[j].getPrice()  ){
                    Product temp = products[j];
                    products[j] = products[j-1];
                    products[j-1] = temp; //从后往前遍历,每次j的结束条件是到达I边界,因为每一次都是最前面的被排好
                }
            }

        }

        for (int i = 0; i < products.length-1; i++) { //i控制每次的边界条件,i层数为length-1
            for (int j = products.length-1; j > i; j--) { //j与j-1构成了指针,j每次都从nums.length-1开始,比如有五个元素的数组,每次都是先[4]和[3]比较
                if (products[j-1].getSale() >= products[j].getSale()){
                    Product temp = products[j];
                    products[j] = products[j-1];
                    products[j-1] = temp; //从后往前遍历,每次j的结束条件是到达I边界,因为每一次都是最前面的被排好
                }
            }

        }
    }

    private static void bubbleSort3(Product[] products){
        for (int i = 0; i < products.length-1; i++) {
            for (int j = products.length-1; j > i; j--) {
                if (products[j].compareTo(products[j-1]) < 0){
                    Product temp = products[j];
                    products[j] = products[j-1];
                    products[j-1] = temp;
                }
            }

        }
    }

    public static void main(String[] args){
        Product product1 = new Product(3,10);
        Product product2 = new Product(1,9);
        Product product3 = new Product(2,9);
        Product product4 = new Product(0,9);
        Product[] products = new Product[]{product1,product2,product3,product4};
        bubbleSort3(products);
        for (Product product : products) {
            System.out.println(product.toString());
        }
    }
}

posted @ 2020-12-13 00:59  EvanMeetTheWorld  阅读(27)  评论(0)    收藏  举报