各种排序算法总结

排序问题是最常见的问题之一,解决该问题的算法也有许多种,简单排序算法包括选择排序、插入排序、冒泡排序等,高级排序算法包括归并排序、快速排序、推排序等等。它们的时间复杂度、空间复杂度以及稳定性见下表。
这里写图片描述
以下是对选择排序、插入排序、冒泡排序、快速排序、归并排序的实现。

package com.ct;

import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.Random;

/**
 * @ Author     :Cao Tuo
 * @ Date       :Created in 10:06 2018/9/7
 * @ Description:provide methods for sorting an array
 */
public class SortMethod {

    public static void main(String[] args){
        int[] A = new int[100000];
        long beforeTime;
        long afterTime;

        initArray(A);
        beforeTime = System.currentTimeMillis();
        SortMethod.SelectSort(A);
        afterTime = System.currentTimeMillis();
        System.out.println("选择排序用时:"+(afterTime-beforeTime)+"ms");
        //show(A);

        initArray(A);
        beforeTime = System.currentTimeMillis();
        SortMethod.InsertSort(A);
        afterTime = System.currentTimeMillis();
        System.out.println("插入排序用时:"+(afterTime-beforeTime)+"ms");
        //show(A);

        initArray(A);
        beforeTime = System.currentTimeMillis();
        SortMethod.BubbleSort(A);
        afterTime = System.currentTimeMillis();
        System.out.println("冒泡排序用时:"+(afterTime-beforeTime)+"ms");
        //show(A);

        initArray(A);
        beforeTime = System.currentTimeMillis();
        SortMethod.QuickSort(A);
        afterTime = System.currentTimeMillis();
        System.out.println("快速排序用时:"+(afterTime-beforeTime)+"ms");
        //show(A);

        initArray(A);
        beforeTime = System.currentTimeMillis();
        SortMethod.MergeSort(A);
        afterTime = System.currentTimeMillis();
        System.out.println("归并排序用时:"+(afterTime-beforeTime)+"ms");
        //show(A);
    }

    public static void initArray(@NotNull int[] A){
        Random random = new Random(0);
        for(int i=0;i<A.length;i++){
            A[i] = (int)(random.nextFloat()*10000);
        }
    }
    // 选择排序
    public static void SelectSort(@NotNull int[] A){
        for(int i=0;i<A.length;i++){
            int min = A[i];
            int index = i;
            for(int j=i+1;j<A.length;j++){
                if(min > A[j]){
                    min = A[j];
                    index = j;
                }
            }
            if(index != i){
                swap(A,i,index);
            }
        }
    }
    // 插入排序
    public static void InsertSort(@NotNull int[] A){
        for(int i=1;i<A.length;i++){
            for(int j=i-1;j>=0;j--){
                if(A[j] > A[j+1]){
                    swap(A,j,j+1);
                }else{
                    break;
                }
            }
        }
    }
    // 冒泡排序
    public static void BubbleSort(@NotNull int[] A){
        for(int i=0;i<A.length;i++){
            for(int j=0;j<A.length-i-1;j++){
                if(A[j] > A[j+1]){
                    swap(A,j,j+1);
                }
            }
        }
    }
    // 快速排序
    public static void QuickSort(@NotNull int[] A){
        QuickSort(A,0,A.length-1);
    }
    public static void QuickSort(@NotNull int[] A,int left,int right){
        if(left > right){
            return;
        }
        int key = A[left];
        int l = left;
        int r = right;
        while(l<r){
            while(key <= A[r] && l<r){
                r--;
            }
            A[l] = A[r];
            while(key > A[l] && l<r){
                l++;
            }
            A[r] = A[l];
        }
        A[l] = key;
        QuickSort(A,left,l-1);
        QuickSort(A,l+1,right);
    }
    // 归并排序
    public static void MergeSort(@NotNull int[] A){
        MergeSort(A,0,A.length-1);
    }
    public static void MergeSort(@NotNull int[] A,int left,int right){
        if(left >= right){
            return;
        }
        MergeSort(A,left,(left+right)/2);
        MergeSort(A,(left+right)/2+1,right);
        merge(A,left,(left+right)/2,right);
    }
    private static void merge(int[] A,int p,int q,int r){
        int[] leftArray = new int[q-p+2];
        int[] rightArray = new int[r-q+1];
        for(int i=0,j=p;j<=q;i++,j++){
            leftArray[i] = A[j];
        }
        leftArray[leftArray.length-1] = Integer.MAX_VALUE;
        for(int i=0,j=q+1;j<=r;i++,j++){
            rightArray[i] = A[j];
        }
        rightArray[rightArray.length-1] = Integer.MAX_VALUE;
        for(int i=0,j=0,k=p;k<=r;k++){
            if(leftArray[i]<=rightArray[j]){
                A[k] = leftArray[i];
                i++;
            }else{
                A[k] = rightArray[j];
                j++;
            }
        }
    }
    // swap A[i] with A[j]
    private static void swap(@NotNull int[] A, int i , int j){
        int temp = A[i];
        A[i] = A[j];
        A[j] = temp;
    }
    // show the elements of array A
    public static void show(int A[]){
        System.out.println(Arrays.toString(A));
    }
}

运行结果如下:
这里写图片描述
可以看到,当数组长度为100000时,归并排序和快速排序效果最好,均比选择排序和插入排序快两个数量级,冒泡排序效果最差

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值