java十大排序的实现和时间复杂度的横向对比

java十大排序的实现和(时间、空间)复杂度的横向对比

一、java十大排序的实现

冒泡排序

private static int[] bobbleSort(int[] arr){
    int temp = 0;
    boolean falg = false;
    for (int i=0;i<arr.length-1;i++){
        for (int k=0;k<arr.length-1-i;k++) {
            if (arr[k] > arr[k + 1]) {
                falg = true;
                temp = arr[k];
                arr[k] = arr[k + 1];
                arr[k + 1] = temp;
            }
        }
        if (!falg){
            break; 
        }else {
            falg = false; 
        }
    }
    return arr;
}

选择排序

private static void selectSort(int[] arr){
    for (int i = 0; i < arr.length - 1; i++) {
        int min = arr[i];
        int j=i;
        for (int k=i+1;k<arr.length;k++){
            if (arr[k]<min){
                min = arr[k];
                j = k;
            }
        }
        if (i!=j) {
            arr[j] = arr[i];
            arr[i] = min;
        }
    }
}

插入排序

private static void insertSort2(int[] arr){
    for (int i = 1; i < arr.length; i++) {
        int insertVal = arr[i]; 
        int insertIndex = i-1; 
        while (insertIndex>=0&&arr[insertIndex]>insertVal){
            arr[insertIndex+1] = arr[insertIndex];
            insertIndex--;
        }
        arr[insertIndex+1] = insertVal;
    }
}

希尔排序

private static void shellSort2(int[] arr) {
    for (int gap = arr.length / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < arr.length; i++) {
            int index = i - gap;
            int temp = arr[i];
            while (index >= 0 && arr[index] > temp) {
                arr[index + gap] = arr[index];
                index -= gap;
            }
            arr[index + gap] = temp;
        }
    }
}

归并排序

public static void fenAndMerge(int[] arr,int left,int right,int[] temp){
    if (left<right){
        int mid = (left+right)/2;
        //向左递归 拆分
        fenAndMerge(arr,left,mid,temp);
        //向右递归 拆分
        fenAndMerge(arr,mid+1,right,temp);
        //合并
        merge(arr,left,mid,right,temp); //见下方merge()方法
    }
}

/**
     *
     * @param arr 需要归并的数组
     * @param left 数组的左边索引
     * @param mid  数组的中间索引
     * @param right 数组的右边索引
     * @param temp 中间数组
     */
public static void merge(int[] arr,int left,int mid,int right,int[] temp){
    int t = 0;
    int j = mid+1;
    int i = left;
    //比较mid左右两边数据 按大小顺序放入temp中
    //1.mid两边都有数据 就一直比较
    while (i<=mid&&j<=right){
        if (arr[i]<=arr[j]){
            temp[t] = arr[i];
            i+=1;
            t+=1;
        }else {
            temp[t] = arr[j];
            j+=1;
            t+=1;
        }
    }
    //2.如果只剩下一边有数据,将数据依次加入到temp中
    while (i<=mid){
        temp[t] = arr[i];
        t+=1;
        i+=1;
    }
    while (j<=right){
        temp[t] = arr[j];
        t+=1;
        j+=1;
    }
    //3.arr数组中索引是固定的,只是逻辑上拆分,需要将排列后的数组中数据返回指定的位置。
    t =0;
    int tempLeft = left;
    while (tempLeft<=right){
        arr[tempLeft]=temp[t];
        t+=1;
        tempLeft+=1;
    }
}

快速排序

public static int[] QuickSort(int[] array, int start, int end) {
    if (array.length < 1 || start < 0 || end >= array.length || start > end) return null;
    int smallIndex = partition(array, start, end);
    if (smallIndex > start)
        QuickSort(array, start, smallIndex - 1);
    if (smallIndex < end)
        QuickSort(array, smallIndex + 1, end);
    return array;
}

public static int partition(int[] array, int start, int end) {
    int pivot = (int) (start + Math.random() * (end - start + 1));
    int smallIndex = start - 1;
    swap(array, pivot, end);
    for (int i = start; i <= end; i++)
        if (array[i] <= array[end]) {
            smallIndex++;
            if (i > smallIndex)
                swap(array, i, smallIndex);
        }
    return smallIndex;
}

public static void swap(int[] array, int i, int j) {
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

堆排序

static int len;
public static int[] HeapSort(int[] array) {
    len = array.length;
    if (len < 1) return array;
    buildMaxHeap(array);
    while (len > 0) {
        swap(array, 0, len - 1);
        len--;
        adjustHeap(array, 0);
    }
    return array;
}
public static void buildMaxHeap(int[] array) {
    for (int i = (len/2- 1); i >= 0; i--) {
        adjustHeap(array, i);
    }
}
public static void adjustHeap(int[] array, int i) {
    int maxIndex = i;
    if (i * 2 < len && array[i * 2] > array[maxIndex])
        maxIndex = i * 2;
    if (i * 2 + 1 < len && array[i * 2 + 1] > array[maxIndex])
        maxIndex = i * 2 + 1;
    if (maxIndex != i) {
        swap(array, maxIndex, i);
        adjustHeap(array, maxIndex);
    }
}

计数排序

public static int[] CountingSort(int[] array) {
    if (array.length == 0) return array;
    int bias, min = array[0], max = array[0];
    for (int i = 1; i < array.length; i++) {
        if (array[i] > max)
            max = array[i];
        if (array[i] < min)
            min = array[i];
    }
    bias = 0 - min;
    int[] bucket = new int[max - min + 1];
    Arrays.fill(bucket, 0);
    for (int i = 0; i < array.length; i++) {
        bucket[array[i] + bias]++;
    }
    int index = 0, i = 0;
    while (index < array.length) {
        if (bucket[i] != 0) {
            array[index] = i - bias;
            bucket[i]--;
            index++;
        } else
            i++;
    }
    return array;
}

桶排序

public static ArrayList<Integer> BucketSort(ArrayList<Integer> array, int bucketSize) {
    if (array == null || array.size() < 2)
        return array;
    int max = array.get(0), min = array.get(0);
    for (int i = 0; i < array.size(); i++) {
        if (array.get(i) > max)
            max = array.get(i);
        if (array.get(i) < min)
            min = array.get(i);
    }
    int bucketCount = (max - min) / bucketSize + 1;
    ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketCount);
    ArrayList<Integer> resultArr = new ArrayList<>();
    for (int i = 0; i < bucketCount; i++) {
        bucketArr.add(new ArrayList<Integer>());
    }
    for (int i = 0; i < array.size(); i++) {
        bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i));
    }
    for (int i = 0; i < bucketCount; i++) {
        if (bucketSize == 1) { 
            for (int j = 0; j < bucketArr.get(i).size(); j++)
                resultArr.add(bucketArr.get(i).get(j));
        } else {
            if (bucketCount == 1)
                bucketSize--;
            ArrayList<Integer> temp = BucketSort(bucketArr.get(i), bucketSize);
            for (int j = 0; j < temp.size(); j++)
                resultArr.add(temp.get(j));
        }
    }
    return resultArr;
}

基数排序

public static void radixSort(int[] arr) {
    //1.求出arr数组中的最大值
    int max = arr[0];
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    //2.求出最大值的位数
    int length = String.valueOf(max).length();
    //基数排序通过二维数组保存原数组中的数据
    int[][] bucket = new int[10][arr.length];
    //3.每个桶中的数据个数不固定,使用一维数组记录每个桶中的元素个数
    int[] bucketElementCount = new int[10];
    //5.由单轮规矩总结
    for (int m=0,n=1;m<length;m++,n*=10){
        //4.第一轮 按个位数数字放入到桶中
        for (int i = 0; i < arr.length; i++) {
            int elementIndex = arr[i] /n % 10;
            bucket[elementIndex][bucketElementCount[elementIndex]] = arr[i];
            bucketElementCount[elementIndex]++;
        }
        //5.取出桶中的数据放入原数组中
        //遍历桶
        int index = 0;
        for (int j = 0; j < bucket.length; j++) {
            //如果桶中有数据,取出并放入到原数组中
            if (bucketElementCount[j] > 0) {
                //遍历每个桶中的元素
                for (int k = 0; k < bucketElementCount[j]; k++) {
                    arr[index] = bucket[j][k];
                    index++;
                }
            }
            //每一轮处理结束需要将bucketElementCount置为0
            bucketElementCount[j] = 0;
        }
    }
}

二、时间复杂度

定义:用来度量算法的运行时间,记作: T(n) = O(f(n))。它表示随着 输入大小n 的增大,算法执行需要的时间的增长速度可以用 f(n) 来描述。

三、空间复杂度

定义:该算法所耗费的存储空间,它也是问题规模n的函数。渐近空间复杂度也常常简称为空间复杂度。空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。

四、java十大排序的横向对比

排序算法平均时间复杂度最坏时间复杂度空间复杂度是否稳定
冒泡排序O(n^2)O(n^2)O(1)
选择排序O(n^2)O(n^2)O(1)不是
插入排序O(n^2)O(n^2)O(1)
希尔排序O(n*log n)O(n^s)O(1)不是
归并排序O(n*log n)O(n*log n)O(n)
快速排序O(n*log n)O(n^2)O(log n)不是
堆排序O(n*log n)O(n*log n)O(1)不是
计数排序O(n+k)O(n+k)O(n+k)
桶排序O(n*k)O(n^2)O(n*k)
基数排序O(n*k)O(n*k)O(n+k)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值