千家信息网

简单算法之9种排序(一)

发表于:2024-11-18 作者:千家信息网编辑
千家信息网最后更新 2024年11月18日,甭管什么,笔者就喜欢凑个9。这次,关于排序的算法还是9种,小结一下。排序的算法,尽管有很多的方法例子,但这次是自己总结的,挺有意思算法希望大家喜欢。直接上代码楼,以下算法,都经过笔者亲测,并修改使之有
千家信息网最后更新 2024年11月18日简单算法之9种排序(一)

甭管什么,笔者就喜欢凑个9。这次,关于排序的算法还是9种,小结一下。排序的算法,尽管有很多的方法例子,但这次是自己总结的,挺有意思算法希望大家喜欢。直接上代码楼,以下算法,都经过笔者亲测,并修改使之有效(粘贴可用)。

package com.css.java.learning.massbag;import java.util.Arrays;/**算法: * 排序相关小结 * @author Red_ant * 20181119 */public class OrderMethod {    /*1、冒泡排序     * 通过相邻两个元素比较的方式,依次选出合适的元素放到     * 数组的第i位。     */    public static int[] bubbleSort(int[] nums){        int num = 0;        for (int i = 0; i < nums.length -1; i++) {            for (int j = 0; j < nums.length - 1 - i; j++) {//两两比较,符合条件的元素居于前面                if(nums[j] > nums[j + 1]){                    num = nums[j];                    nums[j] = nums[j + 1];                    nums[j + 1] = num;                }            }        }        return nums;    }    /*2、选择排序     * 每一趟从待排序列,选择最小的元素放到已排序好的序列末尾,剩下的为待排序序列,     * 重复上述步骤,直至完成。     */    public static int[] selectSort(int[] nums){        int num = 0;        for (int i = 0; i < nums.length -1; i++) {            int index = i;            for (int j = i + 1; j < nums.length; j++) {//选择合适的元素,直接放到数组的第i位                if(nums[index] > nums[j]){                    index = j;                }                if(index != i){                    num = nums[i];                    nums[i] = nums[index];                    nums[index] = num;                }            }        }        return nums;    }    /*3、选择排序:堆排序     * 堆排序是一种树形结构选择排序     * 堆排序需要两个过程,建立堆,堆顶与堆最后一个元素交换位置。所以堆排序有两个函数组成:     * 建堆的***函数,反复调用***函数实现排序的函数     * 基本思路:     * 将序列建成一个堆,根据升序降序选择大顶堆或小顶堆     * 将堆顶元素与末尾元素交换,将最大元素沉到数组末端     * 重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。     */    public static int[] HeapSorts(int[] nums){        //建立大顶        for (int i = nums.length/2 - 1; i >= 0; i--) {            //从第一个非叶子节点从下至上,从右至左调整结构            suitHeap(nums, i, nums.length);        }        //调整堆结构,交换堆顶元素与 末尾元素        for (int j = nums.length - 1; j > 0; j--) {            exchangeNum(nums, 0, j);//交换堆顶元素与末尾元素            suitHeap(nums, 0, j);        }        return nums;    }    private static void exchangeNum(int[] nums, int i, int i2) {        int index = nums[i];        nums[i] = nums[i2];        nums[i2] = index;    }    private static void suitHeap(int[] nums, int i, int length) {        int index = nums[i];//取出当前元素        for (int j = i*2 + 1; j < length; j = j*2+1) {            //从i节点的左节点开始,即2i+1处            if(j+1 < length && nums[j] < nums[j+1]){                //如果,左子节点小于右子节点,j指向右子节点                j++;            }            if(nums[j] > index){                //如果子节点大于父节点,将子节点赋值给父节点                nums[i] = nums[j];                i = j;            }else{                break;            }        }        nums[i] = index;//将index值放到最终位置    }    /*4、java Arrays排序     * 该方法是Arrays类的静态方法,在需要对数组进行排序时,非常好用     */    public static int[] ArraySort(int[] nums){        Arrays.sort(nums);        return nums;    }    /*5、插入排序:直接插入排序     * 将数组分为两部分,将后部分元素逐一与前部分元素比较     * 然后依据比较结果进行移动元素     */    public static int[] insertSort(int[] nums){        //从头部第一个当做已经排序好的,把后面的一个一个的插入到已经排序好的列表中        for (int i = 1; i < nums.length; i++) {            int j;            int index = nums[i];//index为待插入的元素            for (j = i; j > 0 && index < nums[j - 1]; j--) {                nums[j] = nums[j -1];            }            nums[j] = index;        }        return nums;    }    /*6、插入排序:希尔排序     * 建堆,对顶与堆的最后一个元素进行排序     * 希尔排序是插入排序的一种,先取一个小于n的整数作为第一个增量,把文件的全部记录分组。     * 所有距离为d1的倍数的记录放在同一个组中,先在各组内进行直接插入排序。实际上是一种分组插入排序的方法。     */    public static int[] shellSrot(int[] nums){        int index = nums.length/2;        while (index >= 1) {            for (int i = index; i < nums.length; i++) {                if(nums[i] < nums[i - index]){                    int j;                    int x = nums[i];//当前待插入的元素                    nums[i] = nums[i - index];                    for (j = i - index; j >= 0 && x < nums[j]; j = j-index) {                        nums[j + index] = nums[j];                    }                    nums[j + index] = x;//插入元素                }            }            index = index/2;        }        return nums;    }    /*7、交换排序:快速排序     * 基本思想:     * A选择一个基准元素,通常选择第一个元素或最后一个元素     * B通过一趟排序将待排序的记录分割成独立的两部分:记录均值比基准元素值小,元素值比基准元素值大     * C此时基准元素在排序好的正确位置     * D分别对这两部分记录,用同样的方法继续进行排序,直到整个序列有序。     */    public static int[] quickSort(int[] nums, int...is){        int low,hight;        if(is.length == 0){            low = 0;            hight = nums.length - 1;        }else{            low = is[0];            hight = is[1];        }        if(low < hight){//判断,让递归函数退出,否则无限循环            int middle = getMiddle(nums, low, hight);            quickSort(nums, 0, middle - 1);//基准元素小            quickSort(nums, middle + 1, hight);//比基准元素大        }        return nums;    }    //获取,均值    private static int getMiddle(int[] nums, int low, int hight) {        int index = nums[low];//选择基准元素        while (low < hight) {            //从hight开始,找出比基准小的,与low换位置            while (low < hight && nums[hight] >= index) {                hight--;            }            nums[low] = nums[hight];            //从low开始找比基准大,放到之前hight空出来的位置上            while (low < hight && nums[low] <= index) {                low++;            }            nums[hight] = nums[low];        }        //此时low = hight是基准元素的位置,也是空缺的位置        nums[low] = index;        return low;    }    /*     * 8、归并排序     * 基本思想:     * 归并排序是,将两个或两个以上有序表合并成一个新的有序表。     * 即把待排序的序列分为若干个子序列,每个子序列是有序的,然后再把有序序列合并成整体有序序列     */    public static int[] mergeSort(int[] nums){        sortmerge(nums, 0, nums.length - 1);        return nums;    }    private static void sortmerge(int[] nums, int i, int j) {        if(i >= j){            return;        }        //找出中间索引        int middle = (i + j)/2;        //对左边数组进行递归        sortmerge(nums, i, middle);        //对右边数组进行递归        sortmerge(nums, middle + 1, j);        //合并数组        merge(nums, i, middle, j);    }    private static void merge(int[] nums, int i, int middle, int j) {        //创建临时中间量数组        int[] tmpArr = new int[nums.length];        //右数组第一个元素索引        int mid = middle + 1;        //记录临时数组索引        int second = i;        //缓存左侧数组第一个元素的索引        int tmp = i;        while (i <= middle && mid <= j) {            //从两个数组中取出最小的放到临时数组中            if(nums[i] <= nums[mid]){                tmpArr[second++] = nums[i++];            }else{                tmpArr[second++] = nums[mid++];            }        }        //剩余部分依次放入临时数组        while (mid <= j) {            tmpArr[second++] = nums[mid++];        }        while (i <= middle) {            tmpArr[second++] = nums[i++];        }        //将临时数组中内容,拷贝到原数组中        while (tmp <= j) {            nums[tmp] = tmpArr[tmp++];        }    }    /*9、基数排序(桶)     * 将数组中的所有元素按照元素中最长的位数进行统一格式,不足位数的前面补充0     * 然后,一次比较每一位的数字,得到最终的比较结果     * 基本思想:     * A遍历找出最大的数(确定最大的数是几)     * B开辟临时数组,用于中间过程的计算     * C用一个count数组统计原数组中某一位(从低位向高位统计)相同的数据出现的次数;     * D用一个start数组计算原数组中某一位(从最低位向最高位计算)相同数据出现的位置;     * E将桶中数据从小到大用临时数组收集起来;     * F重复(3)(4)(5)直到所有位都被统计并计算过,用临时数组收集起来;     * G将临时数组拷回到原数组中;     */    public static int[] radixSort(int[] nums) {                int exp;    // 指数。当对数组按各位进行排序时,exp=1;按十位进行排序时,exp=10;...                int max = getMax(nums);    // 数组a中的最大值                // 从个位开始,对数组a按"指数"进行排序                for (exp = 1; max/exp > 0; exp *= 10) {                    countSort(nums, exp);                }                return nums;        }    //获取数组中最大的元素    private static int getMax(int[] nums) {        int i, max;            max = nums[0];            for (i = 1; i < nums.length; i++)                    if (nums[i] > max)                            max = nums[i];            return max;    }    /*     * 对数组按照"某个位数"进行排序(桶排序)     * 参数说明:     * exp -- 指数。对数组a按照该指数进行排序。     * (01) 当exp=1表示按照"个位"对数组a进行排序     * (02) 当exp=10表示按照"十位"对数组a进行排序     * (03) 当exp=100表示按照"百位"对数组a进行排序     */    private static void countSort(int[] a, int exp) {        int[] output = new int[a.length]; // 存储"被排序数据"的临时数组        int[] buckets = new int[10];        // 将数据出现的次数存储在buckets[]中        for (int i = 0; i < a.length; i++)            buckets[(a[i] / exp) % 10]++;        // 更改buckets[i]。目的是让更改后的buckets[i]的值,是该数据在output[]中的位置。        for (int i = 1; i < 10; i++)            buckets[i] += buckets[i - 1];        // 将数据存储到临时数组output[]中        for (int i = a.length - 1; i >= 0; i--) {            output[buckets[(a[i] / exp) % 10] - 1] = a[i];            buckets[(a[i] / exp) % 10]--;        }        // 将排序好的数据赋值给a[]        for (int i = 0; i < a.length; i++) {            a[i] = output[i];        }        // 用完清空        output = null;        buckets = null;    }    public static void main(String[] args) {        int[] nums = {1221,232,1242,24,12,4,1,43,14,4,21,4,14,4,1,41,2};        //nums = bubbleSort(nums);冒泡        //nums = selectSort(nums);选择        //nums = ArraySort(nums);数组        //nums = insertSort(nums);插入        //nums = shellSrot(nums);希尔        //nums = HeapSorts(nums);选择排序:堆排序        //nums = quickSort(nums);快速        //nums = mergeSort(nums);归并        nums = radixSort(nums);        for (int k = 0; k < nums.length; k++) {            System.err.println("排序之后的"+nums[k]);        }    }}
0