数据结构——常用的排序方法

稳定性: 两个相等的数据,如果经过排序后,排序算法能保证其相对位置不发生变化,则我们称该算法是具备稳定性的排序算法。

  •   例:2  3(a)  1  4  3(b) 经过排序后为
    
  •   结果为: 1  2  3(a)  3(b)  4 稳定排序
    
  •   结果为: 1  2  3(b)  3(a)  4 不稳定排序
    

如果一个排序是 稳定的的排序 ,那么他就 可以变为 不稳定的排序但如果一个排序本身是 不稳定排序,你 不可能 把它变为 稳定排序。
稳定排序中一般没有跳跃式交换。

常用的 七个 基于比较的 排序

  •     插入排序
    
  •     希尔排序
    
  •  	选择排序
    
  •  	堆排序
    
  •  	冒泡排序
    
  •  	快速排序(重要)
    
  •  	归并排序(重要)
    

直接插入排序
时间复杂度:
最坏情况:O(n^2) 最好情况(有序的情况):O(n)
非常重要:越有序越快
空间复杂度: O(1)
稳定性:稳定排序

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

希尔排序
采用分组的思想,组内进行直接插入排序
时间复杂度:
最坏情况:O(n^2)
最好情况:O(n)
平均:O(n^1.3)
空间复杂度: O(1)
不稳定排序

public static void shellSort(int[] array) {
    int[] drr = {5,3,1};
    for (int i:drr) {
        shell(array,i);
    }
}
public static void shell(int[] array, int gap) {
    for (int i = gap; i < array.length; i++) {
        int t = array[i];
        int j = i - gap;
        for (; j >= 0 ; j -= gap) {
            if (array[j] > t) {
                array[j+gap] = array[j];
            }else {
                array[j+gap] = t;
                break;
            }
        }
        array[j+gap] = t;
    }
}

选择排序
时间复杂度: O(n^2)
空间复杂度:O(1)
不稳定排序

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

堆排序
时间复杂度: O(n*log(2)n)
空间复杂度: O(1)
不稳定排序

public static void adjustDown(int[] array, int root, int end) {
    int p = root;
    int c = p*2 + 1;
    while(c < end) {
        if (c+1<end && array[c]<array[c+1]) {
            c++;
        }
        if (array[c] > array[p]) {
            int t = array[c];
            array[c] = array[p];
            array[p] = t;
            p = c;
            c = 2*p+1;
        }else {
            break;
        }
    }
}

public static void createHeap(int[] array) {
    for (int i = (array.length-1-1)/2; i >= 0; i--) {
        adjustDown(array,i,array.length);
    }
}

public static void heapSort(int[] array) {
    createHeap(array);
    int end = array.length;
    while (end > 0) {
        int t = array[0];
        array[0] = array[end-1];
        array[end-1] = t;
        adjustDown(array,0,end-1);
        end--;
    }
}

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

public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length-1; i++) {
            boolean flg = false;
            for (int j = 0; j < array.length-1-i; j++) {
                if (array[j] > array[j+1]) {
                    int t = array[j];
                    array[j] = array[j+1];
                    array[j+1] = t;
                    flg = true;
                }
            }
            if (flg == false) {
                return;
            }
        }
    }

快速排序(未优化)(递归)
时间复杂度: O(n*log(2)n) 最坏情况: O(n^2)
空间复杂度: O(log(2)n) 最坏情况: O(n)
不稳定排序

public static int partition(int[] array,int low,int high) {
        int t = array[low];
        while (high > low) {
           while (array[high] >= t && high > low) {
               high--;
           }
           array[low] = array[high];
           while (array[low] <= t && high > low) {
               low++;
           }
           array[high] = array[low];
        }
        array[high] = t;
        return high;
    }

    public static void quick(int[] array, int left,int right) {
        if (left >= right) {
            return;
        }
        int par = partition(array,left,right);
        quick(array,left,par-1);
        quick(array,par+1,right);
    }

    public static void quickSort(int[] array) {
        quick(array,0,array.length-1);
    }

归并排序 (递归实现)
时间复杂度: n*log(2)n
空间复杂度: O(n)
稳定排序

 public static void mergeSort(int[] array) {
        mergeSortInternal(array,0,array.length-1);
    }

    public static void mergeSortInternal(int[] array, int low, int high) {
        if (low >= high) {
            return;
        }
        //分解
        int mid = (low + high)>>>1;
        mergeSortInternal(array, low, mid);
        mergeSortInternal(array, mid+1, high);
        //合并
        merge(array,low, mid, high);
    }

    public static void merge (int[] array, int low, int mid, int high) {
        int s1 = low;
        int s2 = mid+1;
        int len = high-low+1;
        int[] ret = new int[len];
        int i = 0;//用来表示ret数组的下标
        //对应位置比较
        while (s1 <= mid && s2 <= high) {
            if (array[s1] <= array[s2]) {
                ret[i++] = array[s1++];
            }else {
                ret[i++] = array[s2++];
            }
        }

        //判断谁没走完,把剩下的数放到ret数组中
        while (s1 <= mid) {
            ret[i++] = array[s1++];
        }

        while (s2 <= high) {
            ret[i++] = array[s2++];
        }

        //将ret数组中的数放到array数组中
        for (int j = 0; j < ret.length; j++) {
            array[j+low] = ret[j];
        }
    }

非基于比较的排序

  • 计数排序
  • 基数排序
  • 桶排序

这里只说基数排序
//获得最大数

public static int getMaxValue(int[] array) {
    int maxValue = array[0];
    for(int value : array) {
        if (maxValue < value) {
            maxValue = value;
        }
    }
    return maxValue;
}

//获得最大数位数
public static int getMaxLenght(int[] array) {
    int maxValue = getMaxValue(array);
    if (maxValue == 0) {
        return 1;
    }
    int maxLenght = 0;
    for (int i = maxValue; i != 0 ; i/=10) {
        maxLenght++;
    }
    return maxLenght;
}

//扩容并存入数据
public static int[] arrayExpand(int[] array, int k) {
    array = Arrays.copyOf(array, array.length+1);
    array[array.length-1] = k;
    return array;
}

//基数排序
public static void radixSort(int[] array) {
    if (array.length == 0) {
        System.out.println("数组为空");
        return;
    }
    int maxLenght = getMaxLenght(array);
    int a = 10;
    int b = 1;
    for (int i = 0; i < maxLenght; i++) {
        int[][] ret = new int[10][0];
        for (int j = 0; j < array.length; j++) {
            int k = array[j]%a/b;
            ret[k] = arrayExpand(ret[k], array[j]);
        }
        int p = 0;
        for (int[] arr :ret) {
            for (int n :arr) {
                array[p++] = n;
            }
        }
        a *= 10;
        b *= 10;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值