八种基本排序算法总结

这三天把基本算法学了一遍,现在做下总结,方便以后查看。
八种排序算法分别是:直接插入排序,希尔排序,冒泡排序,选择排序,堆排序,快速排序,归并排序,基数排序

1.直接插入排序:数据集排序比较好的情况下使用
思路:第i个元素A,如果比前面的数字小,则前面的数字向后移动移位,A继续向前比较,直到不满足条件

private static void insertSort(int[] data) {
for (int i = 1; i < data.length; i++) {
int j = i - 1;
int temp = data[i];
for (; j > 0 && temp < data[j]; j–) {
data[j + 1] = data[j];
}
data[j + 1] = temp;
}
}

2.希尔排序,因为如果数字结合排序很乱,直接插入排序效率会比较低,这是在直接插入排序的改进.

private static void shellSort(int[] data2) {
int pace = data.length;
int k;
int temp;
while (true) {
// 每一次步长减半
pace = pace / 2;
for (int i = 0; i < pace; i++) {
for (int j = pace; j < data.length; j += pace) {
k = j - pace;
temp = data[j];
//如果j位这个数比data[j-pace]小,data[j-pace]的数向后移动
for (; k > 0 && temp < data[k]; k -= pace) {
data[k + pace] = data[k];
}
data[k + pace] = temp;
}
}
//当步长为1时排序完成
if (pace == 1) {
return;
}
}

}

3.冒泡排序,代码实现最简单的排序算法,不过效率最低

private static void bubbleSort(int[] data2) {
int[] data = Arrays.copyOf(data2, data2.length);
startTime = System.nanoTime();

    int len = data.length;
    int temp;
    for (int i = 0; i < len - 1; i++) {
        for (int j = 0; j < len - i - 1; j++) {
            // 如果前面的数字大于后面的数字,就交换,每次循环,相当于把当前最大的数字移动到最后面
            if (data[j] > data[j + 1]) {
                temp = data[j];
                data[j] = data[j + 1];
                data[j + 1] = temp;
            }
        }
    }
}

4.简单选择排序,实现思路跟冒泡排序差不多
private static void selectSort(int[] data2) {
int j;
int temp;
int position;
for (int i = 0; i < data.length; i++) {
j = i + 1;
temp = data[i];
position = i;
for (; j < data.length; j++) {
//如果当前的数小于第i数交换,就交换
if (data[j] < temp) {
temp = data[j];
position = j;
}

        }
        data[position] = data[i];
        data[i] = temp;
    }
}

5.堆排序 测试时效率最高的排序算法(网上都说快速排序效率最高)

private static int[] heapSort(int[] data2) {
    // 建最小堆
    buidMinHeap(data);
    for (int i = 0; i < data.length; i++) {
        int last = data.length - i - 1;
        // 下标为0的数跟last下标的数交换
        int temp = data[0];
        data[0] = data[last];
        data[last] = temp;
        minHeapDown(data, 0, last - 1);// 交换后的数字不在改变
    }

    return data;
    // show(data);
}

// 父节点为 (i-1)/2
private static void buidMinHeap(int[] data) {
    int last = data.length - 1;
    // 最后一个父节点下标
    for (int f = (last - 1) / 2; f >= 0; f--) {
        minHeapDown(data, f, last);
    }

}

/**
 * 最小堆,下沉
 * 
 * @param data
 * @param f   父节点下标
 * @param last   数组最后一个下标
 */
private static void minHeapDown(int[] data, int f, int last) {
    int son = f * 2 + 1;
    int temp = data[f];
    // 保存当前的父节点下标
    int k = f;
    // 如果有子节点
    while (son <= last) {
        // 判断左右子节点大小
        if (son + 1 <= last && data[son] > data[son + 1]) {
            // 若果右节点存在并且比左节点小,父节点与右节点进行比较
            son++;
        }
        // 如果父节点比小的子节点小或等于,不用调整位置
        if (temp <= data[son]) {
            break;
        }
        // 父节点大于子节点,需要交换的情况
        data[k] = data[son];
        k = son;
        son = 2 * k + 1;
    }
    data[(son - 1) / 2] = temp;
}

6.快速排序 参考视频 http://www.iqiyi.com/v_19rrhzyeqs.html

private static void quickSort(int[] data2) {
if (data.length > 0) {
_quickSortStart(data, 0, data.length - 1);
}
// show(data);
}

private static void _quickSortStart(int[] data, int low, int high) {
    if (low < high) {
        int middle = getMiddle(data, low, high);
        // 对低位部分进行排序
        _quickSortStart(data, low, middle - 1);
        // 对高位部分进行排序
        _quickSortStart(data, middle + 1, high);
    }
}

private static int getMiddle(int[] data, int low, int high) {
    int temp = data[low];
    while (low < high) {
        while (low < high && temp <= data[high]) {
            high--;
        }
        data[low] = data[high];

        while (low < high && data[low] <= temp) {
            low++;
        }
        data[high] = data[low];
        data[low] = temp;
    }

    // show(data);
    return low;
}

7.归并排序

private static void mergeSort(int[] data2){
int len=data.length;
if(len>1){
_mergeSort(data,0,len-1);
}
//show(data);

}
private static void _mergeSort(int[] data, int l, int r) {
    if(l==r){
        return;
    }
    int m=(r+l)/2;
    _mergeSort(data, l, m);
    _mergeSort(data, m+1, r);
    merge(data, l, m+1, r);
}

private static void merge(int[] data,int l,int m,int r){
    int[]left=Arrays.copyOfRange(data,l,m );
    int[]right=Arrays.copyOfRange(data, m, r+1);
    int i=0;
    int j=0;
    while(i<left.length && j<right.length){
        if(left[i]<right[j]){
            data[l]=left[i];
            i++;
        }else{
            data[l]=right[j];
            j++;
        }
        l++;
    }
    while(i<left.length){
        data[l]=left[i];
        l++;
        i++;
    }
    while(j<right.length){
        data[l]=right[j];
        l++;
        j++;
    }
}

8.基数排序

private static void radixSort(int[]data2){
//获得最大值
int max=0;
for(int d:data){
if(d>max){
max=d;
}
}

    //计算数字的位数
    int order=1;
    while(max>0){
        max/=10;
        order++;
    }
    List<List> datas=new ArrayList<List>();
    //创建10个集合
    for(int i=0;i<10;i++){
        List<Integer> queue=new ArrayList<>();
        datas.add(queue);
    }

    //进行order次分配和收集
    for(int i=0;i<order;i++){
        for(int j=0;j<data.length;j++){
            //当前位上的数字,比如百位,十位,个位上的数字
            int x = data[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
            List<Integer> list=datas.get(x);
            list.add(data[j]);
            datas.set(x, list);
        }

        int k=0;
        //对一次排序之后进行收集
        for(List que:datas){
            while(que.size()>0){
                data[k]=(int) que.get(0);
                que.remove(0);
                k++;
            }
        }
    }
    //show(data);
}

你可能感兴趣的:(冒泡排序,插入排序,归并排序,希尔排序,排序算法)