java排序算法归纳(常见排序)

        温故可以知新,排序算法不是很难,平时我们排序,java中都自带排序算法,像集合中自带的排序算法,底层实现就是归并排序和二叉树排序,有兴趣的小伙伴可以去看看。

       下面聊聊普通的排序算法,不是特别深奥,直接写一点代码,回顾下算法的一些思想以及实现

1、冒泡排序,

         这个就不说了,直接上代码了,最开始接触算法的时候学习的。

  /**
     * 冒泡排序
     * 时间复杂度O(n*n)
     * @param list
     * @return
     */
    public static List<Integer> sortByBob(List<Integer> list){
        if(list.isEmpty()){
            return new ArrayList<>();
        }
        int length = list.size();
        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j < length-1-i; j++) {
                if(list.get(j)>list.get(j+1)){
                    int temp = list.get(j);
                    list.set(j,list.get(j+1));
                    list.set(j+1,temp);
                }
            }
        }
        System.out.println(JSONArray.toJSONString(list));
        return list;
    }

2、选择排序

       选择排序,我感觉理解起来更简单,甚至我一直以为选择排序就是冒泡排序,因为是一个一个对比的,算法的复杂度也是O(n*n),这个大家了解下就好,一般很少用,太耗性能了,不划算的,来看下代码哈。

  /**
     * 选择排序,和冒泡排序时间复杂度一样,更容易理解
     * 时间复杂度O(n*n)
     * @param list
     * @return
     */
    public static List<Integer> sortByChoose(List<Integer> list){
        if(list.isEmpty()){
            return new ArrayList<>();
        }

        for (int i = 0; i < list.size(); i++) {
            for (int j = i+1; j < list.size(); j++) {
                if(list.get(i)>list.get(j)){
                    int temp = list.get(i);
                    list.set(i,list.get(j));
                    list.set(j,temp);
                }
            }
        }
        System.out.println(JSONArray.toJSONString(list));
        return list;
    }

3、插入排序

       这个也是基础的排序,感觉是比冒泡排序消耗的性能少些,但是,最坏的情况下时间复杂度也是O(n*n),一般默认插入排序的时间复杂度就是O(n*n),这个大伙注意下哈,看下代码。

 /**
     * 插入排序
     * 插入排序思想容易理解,写起来比较绕,就是把j位置上的值往前一位设置,判断当前的数据小于某一位时,停止复制,
     *           把预存的i位置的值赋上去
     * 这个感觉时间复杂度比冒泡少,但是实际上平均时间复杂度是n^2/4+n/2-1/2,最差的结果也是n^2
     * @param list
     * @return
     */
    static public List<Integer> sortByInsert(List<Integer> list){

        for (int i = 1; i < list.size(); i++) {
            int j ;
            if(list.get(i-1)>list.get(i)){
                int temp = list.get(i);
                for (j = i-1;j>=0&&temp<list.get(j);j--){
                    list.set(j+1,list.get(j));
                }
                list.set(j+1,temp);
            }
        }
        System.out.println(JSONArray.toJSONString(list));
        return list ;
    }

4、快速排序

         快速排序是一种分段递归的思想,时间复杂度是nlogN,是一种比较成熟的排序算法。好了,看下代码。

 /**
     * 快速排序
     * (1)首先设定一个分界值,通过该分界值将数组分成左右两部分。 [2]
     * (2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
     * (3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
     * (4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
     * @return
     */
    public static List<Integer> quickSort(List<Integer> list,Integer start,Integer end){
        if (list.isEmpty()) return new ArrayList<>();
        int i = start;
        int j = end;
        int mark = list.get(start);

        while (i<j){
            while ((i<j)&&list.get(j)>mark){
                j--;
            }
            while ((i<j)&&(list.get(i)<mark)){
                i++;
            }
            if((list.get(i)==list.get(j))&&i<j){
                i++;
            }else {
                int temp = list.get(i);
                list.set(i,list.get(j));
                list.set(j,temp);
            }
        }
        if(i-1>start) list = quickSort(list,start,i-1);
        if(j+1<end) list = quickSort(list,j+1,end);

        return list;
    }

5、归并排序

       这种排序算法应该说是比较接近我们的使用的,上面我也说了,集合排序中使用了归并排序,另外,MYSQL中的排序用的也是归并排序。归并排序是比较好理解的,效率也很高,不过比较耗费内存,但是这种消耗对于大多数系统来说都是可以接受的。看下代码。

 /**
     * 归并排序递归
     * @param list
     * @param left
     * @param right
     * @return
     */
    public static List<Integer> mergeSort(List<Integer> list,int left,int right){
        if(left<right){
            int mid = (left+right)/2;
            mergeSort(list,left,mid);
            mergeSort(list,mid+1,right);
            mergePlatfrom(list,left,mid,right);
        }
        return list;
    }

    /**
     * 归并排序是底层实现
     * @param list
     * @param left
     * @param mid
     * @param right
     */
    static public void mergePlatfrom(List<Integer> list,int left,int mid,int right){
        List<Integer> temp = new ArrayList<>();  //存放排序后的新队列
        int i = left;
        int j = mid+1;
        int t = 0;
        while (i<=mid && j<=right){ //归并会从中间分开,从两侧依次拿出一个数据进行对比,然后放到新数据集合里面,这样新的数据集合里面的数据就是有序的
            if(list.get(i)<=list.get(j)){
                temp.add(list.get(i++));
            } else {
                temp.add(list.get(j++));
            }
        }
        //表示左侧的数据很大,右侧的数据已经比完了,左侧还有多个数据,因为默认是有序的(会递归),所以直接放进新的数据集合里
        while (i<=mid){
            temp.add(list.get(i++));
        }
        //同理,表示右侧的数据很大,左侧的数据已经比完了,右侧还有多个数据,默认有序(会递归),也直接放进新的数据集合里
        while (j<=right){
            temp.add(list.get(j++));
        }
        //把排序后的新的数据集合放到原来的数据集合里面
        t = 0;
        while (left <= right){
            list.set(left++,temp.get(t++));
        }
    }

      代码写的不是特别经典,但还算简单易懂,实现了算法中主要的逻辑。想回顾下排序算法的小伙伴可以看下哈。

No sacrifice,no victory~

猜你喜欢

转载自blog.csdn.net/zsah2011/article/details/109057866