美文网首页数据结构与算法
常用排序算法(二)

常用排序算法(二)

作者: Chuck_Hu | 来源:发表于2017-05-20 10:15 被阅读3次

之前的文章讲解了三种时间复杂度为O(n^2)的简单排序算法,本篇介绍另外两种经典排序算法希尔排序和归并排序。这两种算法中,希尔排序理解起来不太容易,归并排序比较容易理解但代码量偏多。在面试的过程中被问到的几率比较小。

希尔排序

希尔排序是插入排序的一种,是对前一篇所讲直接插入排序的优化方法,又称缩小增量排序。
基本思想:将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;然后再选择一个更小的增量,再将数组分割为多个子序列进行排序直到选择增量为1,即使用直接插入排序,使最终数组成为有序。
增量的选择:在每趟的排序过程都有一个增量,至少满足一个规则 增量关系 d[1] > d[2] > d[3] >..> d[n] = 1 (n趟排序)。
增量的大小对排序算法性能也有影响,一般而言,增量的初始值设为(数组长度 / 2)之后的每趟排序中,数组长度变为之前的1/2,直到 增量为1时结束排序。
希尔排序过程比较复杂,这里有个短视频,可以帮助理解:http://v.youku.com/v_show/id_XMjU4NTcwMDIw.html
还是直接上代码吧:

public void shellSort(int[] nums){
    int increment = nums.length;
    int temp;
    while(true){
        increment = (int)Math.ceil(increment / 2);
        for(int i = 0; i < increment; i += increment){
            for(int j =i + increment; j < nums.length; j++){
                int k = j - increment;
                temp = nums[j];
                for(; k >= 0 && nums[k] > temp; k -= increment){
                    nums[k + increment] = nums[k];
                }
                nums[k + increment] = temp;
            }
        }
        if(increment == 1){
            break;
        }
    }
}
归并排序

归并排序运用了基础算法中的分治思想,将数先对半拆分为两个数组,在对分开的数组做拆分,以此类推直到拆分出的数组的长度为1时停止拆分开始归并。
归并的方式也很简单,就是创建一个大小为两个数组长度之和的新数组,然后两个数组都从头开始遍历,按顺序加入新数组,新产生的数组必定是排好序的,再将其与其他数组进行归并,直至整个数组排序完成。
思路很简单,但是代码量还是挺大的,虽然比不上堆排序,但毕竟堆排序相较于归并而言显得更加高级,相同的时间复杂度但空间复杂度堆排序优于归并排序。


归并过程

为了方便理解,减少代码量,本文给出归并排序的递归实现方式:

//归并的主方法
public 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 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 cnt = 0;
    while(i <= mid && j <= high){
        if(nums[i] < nums[j]){
            temp[cnt++] = nums[i++];
        }else{
            temp[cnt++] = nums[j++];
        }
    }
    while(i <= mid){
        temp[cnt++] = nums[i++];
    }
    while(j <= high){
        temp[cnt++] = nums[j++];
    }
    for(i = 0; i < temp.length; i++){
        nums[i + low] = temp[i];
    }
}

本篇介绍的两种排序算法在面试中不常被问到,可能还没有在笔试中考到的频率高,但也希望理解其思想,不会写也得会说吧。

相关文章

  • 算法04-棋牌游戏常用排序算法

    算法04-棋牌游戏常用排序算法 一、介绍 棋牌游戏常用排序算法包括:链式基数排序、插入排序、希尔排序。 二、链式基...

  • python 排序算法

    文章概述 介绍各大常用经典的排序算法和效率,以及python实现常用算法(冒泡排序,选择排序,快速排序,插入排序)...

  • 常用的排序算法

    常用的排序算法 常用的排序算法插入排序折半插入排序shell 排序冒泡排序选择排序快速排序基数排序归并排序堆排序K...

  • 常用算法

    常用排序算法

  • 常见排序算法

    常用排序算法

  • 全面介绍9种常用的排序算法

    本篇给大家介绍几种软件工程中常用的排序算法 所有排序算法的核心的代码都在《常用排序算法核心代码》[https://...

  • 算法学习(1)-排序算法

    八大排序算法九大排序算法再总结[经典排序算法][集锦][直观学习排序算法] 视觉直观感受若干常用排序算法 快速排序...

  • Java语言——数组排序算法

    数组有很多常用的算法,包括冒泡排序、直接选择排序和反转排序。 一、冒泡排序 冒泡排序是最常用的数组排序算法之一,它...

  • Python一行代码实现快速排序

    上期文章排序算法——(2)Python实现十大常用排序算法为大家介绍了十大常用排序算法的前五种(冒泡、选择、插入、...

  • 常用排序算法

    常用的排序算法 在此总结一下常用排序算法的代码实现 #include using namespace std;t...

网友评论

    本文标题:常用排序算法(二)

    本文链接:https://www.haomeiwen.com/subject/ortuxxtx.html