五种常见排序算法的实现和时间复杂度

一、冒泡排序

1.算法实现:

public class BubbleSort {
    public static void main(String[] args) {
        int[] array = new int[]{6,5,4,3,2,1};
        bubbleSort(array);
        System.out.println(Arrays.toString(array));

    }
    public static int[] bubbleSort(int[] array){
        int temp = 0;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length-i-1; j++){
                if (array[j] > array[j+1]){
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }
        return array;
    }
}

2.冒泡排序时间复杂度(稳定):

  • 最优:O( n ) ;
  • 最差:O( n^2 ) ;
  • 平均:O( n^2 ) ;

二、 选择排序

1.算法实现:

public static int[] selectSort(int[] array){
	int temp = 0;
	for (int i = 0; i < array.length-2; i++){
		int minIndex = i;
		for (int j = i+1; j < array.length; j++){
			if (array[minIndex] > array[j]){
                minIndex = j;  //更新最小值下标
                temp = array[j];  //将最小值存入temp
            }
            //最小值交换到下标i的位置,原array[i]值交换到minIndex位置
            array[minIndex] = array[i]; 
            temp = array[i] ;
		}
	}
}

2.选择排序时间复杂度:

//稳定性:不稳定
最好、最差、平均时间复杂度均为:O(n^2)

三、插入排序

1.算法实现:

public static int[] insertSort(int[] array){
    for (int i = 1; i < array.length; i++){
        int temp = 0;
        for (int j = i; j > 0; j--){
            if (array[j] < array[j-1]){
                temp = array[j];
                array[j] = array[j-1];
                array[j-1] = temp;
            }
        }
    }
    return array;
}

2.插入排序时间复杂度:

时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定

四、希尔排序

1.算法实现

public static int[] shellSort(int[] array) {
    //设定步长
    int d = 1;
    while (d < array.length / 2) {
        d = 2 * d + 1;
    }
    
    while (d >= 1) {
        for (int i = d; i < array.length; i++) {
            int temp = 0;
            for (int j = i; j >= d; j -= d) {  //按照步长分组
                if (array[j] < array[j - d]) {  //分组进行插入排序,逆序比较大小
                    temp = array[j];
                    array[j] = array[j - d];
                    array[j - d] = temp;
                } else {
                    break;
                }
            }
        }
        d = d / 2;  //一趟之后缩小步长继续排序
    }
    return array;
}

2.时间复杂度

最好的情况复杂度为O(n);最差的情况是O(n^2),但平均复杂度要比直接插入小,不稳定算法

四、归并排序

1.算法实现

public class MergeSort {
    
    public static void main(String[] args) {
        Integer[] a = {6,5,4,2,7,1,2};
        sort(a);
        System.out.println(Arrays.toString(a));
    }
    //定义一个辅助组数组
    private static Comparable[] assist;

    //比较Compare元素大小
    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    //两个数组元素交换位置
    private static void exchange(Comparable[] a, int i, int j) {
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    //对数组a进行排序
    public static void sort(Comparable[] a) {
        //1.初始化辅助数组
        assist = new Comparable[a.length];
        //2.定义下表low,high
        int low = 0;
        int high = a.length - 1;
        //3.调用重载方法sort,对low-high进行排序
        sort(a, low, high);
    }

    //重载的sort方法
    public static void sort(Comparable[] a, int low, int high) {
        //安全性校验
        if (high <= low) {
            return;
        }
        //分组
        int mid = low + (high - low) / 2;

        //继续对每一组进行排序
        sort(a,low,mid);
        sort(a,mid+1,high);
        //归并
        merge(a,low,mid,high);
    }

    //对分组数据进行归并
    public static void merge(Comparable[] a,int low,int mid, int high){
        //定义三个指针
        int i = low;
        int p1 = low;
        int p2 = mid + 1;
        //遍历,移动两个指针,小的值放到辅助数组对应的位置
        while (p1 <= mid && p2 <=high){
            if (less(a[p1],a[p2])){
                assist[i++] = a[p1++];
            }else {
                assist[i++] = a[p2++];
            }
        }
        //遍历第一个分组,走完指针,并把没比较的值装入辅助数组对应位置
        while (p1 <= mid){
            assist[i++] = a[p1++];
        }
        //遍历第二个分组,走完指针,并把没比较的值装入辅助数组对应位置
        while (p2 <= high){
            assist[i++] = a[p2++];
        }
        //遍历辅助数组,装回原来数组
        for (int index=low; index <= high; index++){
            a[index] = assist[index];
        }
    }
}

2.时间复杂度:

O(nlogn)

五、快速排序

1.算法实现

(1)

public class QuickSort {
    public static void main(String[] args) {
        Integer[] a = {3,5,4,1,2,8,7,2,3};
        sort(a);
        System.out.println(Arrays.toString(a));
    }

    //比较Compare元素大小
    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    //两个数组元素交换位置
    private static void exchange(Comparable[] a, int i, int j) {
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    //对数组a进行排序
    public static void sort(Comparable[] a) {
        //定义下表low,high
        int low = 0;
        int high = a.length - 1;
        //3.调用重载方法sort,对low-high进行排序
        sort(a, low, high);
    }

    //对数组low-high的元素排序
    public static void sort(Comparable[] a, int low, int high) {
        //安全性校验
        if (low > high) {
            return;
        }
        //对左右子组进行分组
        int partition = partition(a, low, high);
        //让左子组有序
        sort(a, low, partition - 1);
        //让右子组有序
        sort(a, partition + 1, high);
    }

    //对数组a从low-high索引分组,并返回分组界限对应索引
    public static int partition(Comparable[] a, int low, int high) {
        //确定分界值
        Comparable key = a[low];
        //定义左右两个扫描指针
        int left = low;
        int right = high + 1;
        //切分
        while (true) {
            //right指针逐步向左,寻找小于key的值
            while (less(key, a[--right])) {
                if (right == low) {
                    break;
                }
            }
            //left指针逐步向右,寻找大于key的值
            while (less(a[++left], key)) {
                if (left == high) {
                    break;
                }
            }
            //判断left是否大于right,若是,说明扫描完毕
            if (left >= right){
                break;
            }else {
                exchange(a,left,right);
            }
        }
        //交换分界值位置
        exchange(a,low,right);
        //返回的是分界值的索引,进行下一次分组
        return right;
    }
}

(2)第二种算法实现(转载于[puber~]的博客)

public static void quickSort(int[]numbers,int start,int end){
    if(start<end){
        int base=numbers[start];//选定的基准值
        int temp;//记录临时中间值
        int i=start,j=end;
        do{
            while ((numbers[i]<base)&&(i<end))
                i++;
            while ((numbers[j] > base) && (j>start))
            j--;
if(i<=j){
    temp=numbers[i];
    numbers[i]=numbers[j];
    numbers[j]=temp;
    i++;
    j--;}}
        while(i<=j);
        if(start <j)
            quickSort(numbers,start,j);
        if(end>i)
            quickSort(numbers,i,end);
}
        }

    }
}
————————————————
版权声明:本文为CSDN博主「puber~」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42594761/article/details/107523759

2.快速排序时间复杂度

  • 最优O(nlogn)
  • 最差O(n^2)
  • 平均O(nlogn)

你可能感兴趣的:(排序算法,java)