zoukankan      html  css  js  c++  java
  • 排序算法

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

    分类

    比较类:

    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;
        }
    }
    
    
  • 相关阅读:
    函数
    python操作文件
    POJ-2689-Prime Distance(素数区间筛法)
    POJ-2891-Strange Way to Express Integers(线性同余方程组)
    POJ-2142-The Balance
    POJ-1061-青蛙的约会(扩展欧几里得)
    Educational Codeforces Round 75 (Rated for Div. 2) D. Salary Changing
    Educational Codeforces Round 75 (Rated for Div. 2) C. Minimize The Integer
    Educational Codeforces Round 75 (Rated for Div. 2) B. Binary Palindromes
    Educational Codeforces Round 75 (Rated for Div. 2) A. Broken Keyboard
  • 原文地址:https://www.cnblogs.com/hugoyu/p/14686969.html
Copyright © 2011-2022 走看看