• 排序算法


    对排序算法做一个总结吧。先提交,回头再补吧

    分类

    比较类:

    1. 插入法:
    • 插入排序

    遍历未排序的列,将遍历到的每个元素插入到有序序列的适当位置。

    • 希尔排序。

    先将待排序的数组分成若干个子数组排序

    1. 选择法:包括选择排序和堆排序
    • 选择排序

    选择第 i 小的元素与第 i- 1 的位置交换

    1. 交换法:包括冒泡排序和快速排序

    非比较类

    1. 计数排序

    2. 桶排序

    3. 基数排序

    复杂度和稳定性

    不稳定排序口诀:一 堆 希尔 快 选!

    1. 插入法

    插入排序

    public class InsertSort {
        public static void main(String[] args) {
            int arr[] = {17, 3, 25, 14, 20, 9};
            System.out.println("排序前的数组:");
            System.out.println(Arrays.toString(arr));
    
            insertSort(arr);
            System.out.println("排序后的数组:");
            System.out.println(Arrays.toString(arr));
        }
    
    
        public static void insertSort(int arr[]) {
            int len = arr.length;
            //数组的第一个元素默认有序的,所以从 1 开始遍历
            for (int i = 1; i < len; i++) {
                int temp = arr[i];
                int j = i - 1;
                //遍历待排序元素前面的元素,若大于待排序的元素后移一位
                while(j >= 0 && arr[j] > temp){
                    arr[j + 1] = arr[j];
                    j--;
                }
                //遍历结束,将待排序的元素插入到所在的位置
                arr[j + 1] = temp;//注意是 j + 1
            }
        }
    }
    
    

    希尔排序

    希尔排序:也是一种插入排序
    1,把记录按下标的一定增量分组(例如有n个数,先分成n/2组,对每组进行排序。
    2,然后分成n/2/2组,进行排序,
    3,直到n/2/2...=1,

    public class ShellSort {
        public static void main(String[] args) {
            int arr[] = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
            shellSort(arr);
            System.out.println(Arrays.toString(arr));
        }
    
        public static void shellSort(int arr[]) {
            //第一个for循环是将原数组分组
            for (int gap = arr.length / 2; gap > 0 ; gap /= 2) {
    
                //后面同插入排序一样,间隔 1 换成了 gap
                for (int i = gap; i < arr.length ; i++) {
                    int j = i - gap;
                    int temp =arr[i];
                    while(j >= 0 && arr[j] > temp) {
                        arr[j+gap] = arr[j];
                        j -= gap;
                    }
                    arr[j + gap] = temp;
                }
    
            }
    
        }
    }
    

    选择排序

    在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。

    public class SelectSort {
        public static void main(String[] args) {
            for (int i = 0; i < arr.length - 1; i++) {
                int temp = 0;
                int index = i; // 用来保存最小值得索引
    
                // 寻找第i个小的数值
                for (int j = i + 1; j < arr.length; j++) {
                    if (arr[index] > arr[j]) {
                        index = j;
                    }
                }
    
                // 将找到的第i个小的数值放在第i个位置上
                temp = arr[index];
                arr[index] = arr[i];
                arr[i] = temp;
            }
        }
    }
    

    堆排序

    3. 堆的概念

    堆是一棵顺序存储的完全二叉树。

    完全二叉树

    ,称为大顶堆;,称为小顶堆。

    • 小根堆:或者每个结点的值都小于或等于其左右孩子结点的值。

    • 大根堆:每个结点的值都大于或等于其左右孩子结点的值。

    同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子:

    该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:

    大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]

    小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]

    冒泡排序

    它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换

    public class BubbleSort {
        public static void main(String[] args) {
            int arr[] = {17, 3, 25, 14, 20, 9};
            System.out.println("排序前的数组:");
            System.out.println(Arrays.toString(arr));
    
            bubbleSort(arr);
            System.out.println("排序后的数组:");
            System.out.println(Arrays.toString(arr));
        }
    
    
        public static void bubbleSort(int arr[]) {
            int len = arr.length;
            for (int i = 0; i < len - 1; i++) {
    
                for (int j = arr.length - 1; j > i; j--) {
                    // 比较相邻的元素,如果前面的数大于后面的数,则交换
                    if (arr[j - 1] > arr[j]) {
                        int temp = arr[j - 1];
                        arr[j - 1] = arr[j];
                        arr[j] = temp;
                    }
                }
            }
        }
    }
    
    

    快速排序

    基本思想

    1.在待排序的元素任取一个元素作为基准(通常选第一个元素,但最的选择方法是从待排序元素中随机选取一个作为基准),称为基准元素;

    ​ 2.将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边;

    ​ 3.对左右两个分区重复以上步骤直到所有元素都是有序的。

    • 优化:基准值的选取 选择中间值 int m = low + (high - low) / 2;//数组中间元素的下标
    public class QuickSort {
        public static void main(String[] args) {
            int n = 100000;
            Random random = new Random(n);
            int[] array = {3,5,4,3,2,1,5,7,4,0};
    
            System.out.println("排序前数组:" + Arrays.toString(array));
            quickSort(array,0,array.length - 1);
    
            System.out.println(Arrays.toString(array));
        }
        //快排的实现
        public static void quickSort(int[] arr, int l, int r) {
            if(l >= r) return;
            int i = l , j = r;
            
            while (i < j) {
                while (i < j && arr[j] >= arr[l]) j--;
                while (i < j && arr[i] <= arr[l]) i++;
                swap(arr, i ,j);
            }
            swap(arr, i, l);
            quickSort(arr, l, i - 1);
            quickSort(arr, i + 1, r);
        }
        //交换数组中的两个元素
        public static void swap(int[] arr, int i, int j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    
    
  • 相关阅读:
    移动端,多屏幕尺寸高清屏retina屏适配的解决方案
    angular 关于 factory、service、provider的相关用法
    2016最新手机号码正则、身份证JS正则表达式
    凸包总结
    BZOJ 3653: 谈笑风生(DFS序+可持久化线段树)
    BZOJ 3652: 大新闻(数位DP+概率论)
    BZOJ 1062: [NOI2008]糖果雨(二维树状数组)
    纪中集训 Day 8 & Last Day
    纪中集训 Day 7
    纪中集训 Day 6
  • 原文地址:https://www.cnblogs.com/hugoyu/p/14686969.html
Copyright © 2020-2023  润新知