软考 - 排序算法

1.总览

在这里插入图片描述

1.待操作数组

private static int[] ori = {30, 70, 40, 60, 10, 90, 20, 50, 80, 100};

2.直接插入排序(O(n2))

原理:当插入第i个元素时,R1,R2 … Ri-1已经基本有序,将i元素和R1,R2 … Ri-1比较,插入合适的位置。

实现一(原理直译成代码,用两个数组,将原数组元素逐个插入新数组):

    public static int[] straightInsertionSort(int[] ori) {
        //初始化sort
        int [] sort = new int[ori.length];
        //逐个将ori元素插入sort
        for (int i = 0; i < ori.length; i++) {
            int ele = ori[i];
            if(i == 0){
                //sort 为空,ele 放入第一位置
                sort[0] = ele;
            }else {
                //sort 不为空,ele 与 sort 逐个比较
                for (int j = 0; j < sort.length; j++) {
                    if(ele<sort[j]){
                        //ele 小于 当前sort,ele 放入当前位置,sort 其余值后移
                        for (int k = sort.length-1 ; k>j ; k--){
                            sort[k] = sort[k-1];
                        }
                        sort[j] =ele;
                        break;
                    }else if(0==sort[j+1]){ //由于int数组初始化后,每一位默认值都是0,如果下一位为0,当前位就是最后一位
                        //ele 比sort最后一个元素大,放入最后一个位置
                        sort[j+1] =ele;
                        break;
                    }else {
                        //比当前sort大,且当前sort不是最后一个值,就和下一个sort比较
                        continue;
                    }
                }
            }
        }
        return sort;
    }

3.希尔排序

原理:R1,R2 … Ri-1,取一个小于i的整数d1作为第一个增量,将所有距离间隔d1的元素放到一组(头和尾,不包括中间),组内直接选择排序;然后取第二个增量d2<d1重复分组和排序,直至dt=1;


4.直接选择排序

原理:R1,R2 … Ri-1,将最小的元素与第1个位置元素交换;在剩余其他元素中选出最小的元素与第2个位置交换;…直至整体都排列好。

    public static int[] straightSelectSort(int[] ori) {
        int minIndex = 0;//最小数值角标
        int temp = 0;//交换临时空间
        for (int i = 0; i < ori.length; i++) {
            minIndex = i;//最小数值角标初始化为当前i
            //当前剩余未排序的数组中 选出最小的元素的角标
            for (int j = i + 1; j < ori.length; j++) {
                if (ori[minIndex] > ori[j]) {
                    minIndex = j;
                }
            }
            //将最小位置与当前第i位交换
            temp = ori[i];
            ori[i] = ori[minIndex];
            ori[minIndex] = temp;
        }
        return ori;
    }

5.堆排序

5.1.堆的分类

大顶堆:所有父节点都比子节点大;用于从大到小排列;
小顶堆:所有父节点都比子节点小;用于从小到大排列;

5.2.原理:

R1,R2 … Ri-1,将所有元素构建成小顶堆,取出根节点即为最小值。重新调整堆结构,再取出根节点即为次小值…堆排序适合取出前n个值。

5.3. 堆排序方法:

小顶堆的构造方法:先将所有值最为节点构成完全二叉树,从最后一个节点到根节点,根据小顶堆的调整方法调整;
小顶堆的排序方法:取出根节点后,把完全二叉树的最后一个节点放到根节点的位置,从根节点开始,根据小顶堆的调整方法调整;
小顶堆的调整方法:检查当前左右子节点是否都比根节点大,不满足,则交换最小子节点与父节点的位置。如果调整后子节点不为叶子节点,则递归调整以该叶子节点为根节点的树;

在这里插入代码片

6.冒泡排序

原理:相邻的元素进行比较和交换,将排序码小的元素逐渐从底部移到顶部;整个过程就像是水底的气泡逐渐上冒;

    public static void bubbleSort(int[] ori){
        int temp = 0;
        //外层循环,每次循环都选出一个最大得放置在数组最后
        for (int i = 0; i < ori.length-1; i++) {
            //内层循环,数组末尾放置好的元素不在动
            for (int j = 0; j < ori.length-1-i; j++) {
                if (ori[j] > ori[j+1]) {
                    //相邻两个数比较,大的右移
                    temp = ori[j];
                    ori[j] = ori[j+1];
                    ori[j+1] =temp;
                }
            }
        }
    }

7.快速排序

原理:
分治法(将原问题分解成若干规模更小单结构和原问题相似的子问题,通过递归的解决子问题,将子问题的解组合成原问题的解)
第一步:待排序数组中 ,取一个数作为基准,将所有记录分成两组,第1组都小于基准,第2组都大于基准;
第二布:采用相同的方法对左右两组进行排序,直到所有记录排到相应的位置;

    /*
    * @Description: 快速排序
    * @param arr: 待排序数组
	 * @param begin: 开始元素角标
	 * @param end: 末尾元素角标
    * @return void
    * @see
    */
    private static void quickSort(int[] arr, int begin, int end) {
        if(begin<end){
            int index = patition(arr,begin,end);//基准角标(index左侧元素都比arr[index]小,index右侧元素都比arr[index]大)
            quickSort(arr,begin,index-1);//递归对分区的左侧快速排序
            quickSort(arr,index+1,end);//递归对分区的右侧快速排序
        }
    }
    /*
    * @Description: 以最后一个元素最为元素基准,将数组分册两个区域
    * @param arr: 带分区数组
	 * @param begin: 开始元素角标
	 * @param end: 末尾元素角标
    * @return int 基准角标
    * @see
    */
    private static int patition(int[] arr, int begin, int end) {
        int index = begin-1;//基准 初始角标
        int patition = arr[end];//基准数值 取最后一个元素的值
        for (int i = begin; i <= end-1; i++) {
            if(arr[i]<=patition){//当前值比基准值小
                index++;//index角标右移一位
                swap(arr,i,index);//把当前元素和index元素的数值交换
            }
        }
        //index角标右移一位的角标,就是第一个比基准数值大的元素,交换两者位置,就实现了快速排序的分区
        swap(arr,++index,end);
        return index;
    }
        /*
     * @Description: 交换数组两个元素的数值
     */
    private static void swap(int[] arr, int x, int y) {
        int temp = arr[x];
        arr[x] = arr[y];
        arr[y] = temp;
    }

8.归并排序

原理:先将整个待排序数组分成若干子表;完成子表内的排序;将两个或两个以上的有序子表合并成一个新的有序表(合并过程:比较A[i]和B[j]的排序码,将较小的元素复制到R[k]中,并令i(或j)和k分别加1,如此循环下去,知道A或B比较复制完,将另一个有序表剩余元素复制到R中);

9.基数排序

原理:适用于元素很多,但是关键字很少的序列;例如,多个百以内的数字排序,关键字只有三个,个位,十位,百位。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
排序是计算机科学中常见的操作,它将一组元素按照特定的顺序重新排列。排序算法的目标通常是将元素按照升序或降序排列。 常见的排序算法有很多种,每种算法都有不同的时间复杂度和空间复杂度。以下是几种常见的排序算法: 1. 冒泡排序(Bubble Sort):比较相邻的两个元素,如果顺序不正确就交换位置,每次遍历将一个最大(最小)的元素移到最后(最前)。时间复杂度为O(n^2)。 2. 插入排序(Insertion Sort):将数组分为已排序和未排序两部分,每次从未排序部分取出一个元素,插入已排序部分的适当位置。时间复杂度为O(n^2)。 3. 选择排序(Selection Sort):每次从未排序部分选择一个最小(最大)的元素放到已排序部分的末尾。时间复杂度为O(n^2)。 4. 快速排序(Quick Sort):选取一个基准元素,将数组划分为两个子数组,小于基准元素的放在左边,大于基准元素的放在右边,然后对子数组进行递归排序。时间复杂度平均情况下为O(nlogn),最坏情况下为O(n^2)。 5. 归并排序(Merge Sort):将数组递归分成两个子数组,然后对子数组进行排序,最后将两个已排序的子数组合并成一个有序数组。时间复杂度为O(nlogn)。 6. 堆排序(Heap Sort):将数组构建成一个最大(最小)堆,每次从堆顶取出最大(最小)元素放到已排序部分的末尾,然后调整堆使其满足堆的性质。时间复杂度为O(nlogn)。 这里只介绍了几种常见的排序算法,每种算法都有其适用的场景和优缺点。在实际应用中,根据数据规模和性能要求选择合适的排序算法非常重要。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值