经典十大排序算法【Java版完整代码】
写在前面的话
十大排序算法对比
冒泡排序
快速排序
直接选择排序
堆排序
归并排序
插入排序
希尔排序
计数排序
桶排序
基数排序
完整测试类
写在前面的话
       虽然已经有很多人总结过这十大排序算法,优秀的文章也不少,但是Java完整版的好像不多,还存在某些文章代码存在错误的情况,同时也为了自己练手,决定把所有的写一遍巩固下,同时也真诚的希望阅读到这篇文章的小伙伴们可以自己去从头敲一遍,不要粘贴复制!希望我的文章对你有所帮助,每天进步一点点!!!

我用通俗的理解写下对算法的解释,对某个算法的运行过程不是很理解的话或者想看比较官方的解释的话,单独搜索某个算法,看几篇不同的解释,就可以有自己的理解了,这里我主要展示代码以及进行通俗的解释!整起来,再强调一次,一定要自己敲一遍,这样才能理解的更深刻!

十大排序算法对比

关于最后一列的稳定性,我稍微解释下,例如对序列:1 2 4 2 6 排序,序列中存在两个2,如果我们把这两个2标记上(让他俩不同),排序之后,前面的2还在前面,那么就称这种排序是稳定的,反之不稳定。

冒泡排序
简单解释:
       原理就如算法名字一样,就像水中的气泡一样,每次我都把最大的或最小的放到最后面,这样总共需要n-1趟即可完成排序,这就是第一层循环,第二次循环就是遍历未被固定的那些数(理解成数组左边的数,因为每层循环都会把最大或最小的数升到最右边固定起来,下次就不遍历这些数了),两层循环遍历结束后,所有的数就排好序了。
       两层循环所以冒泡排序算法的时间复杂度是O(n 2 n^{2}n 
2
 ),是一个非常高的时间复杂度,我在下面的代码进行了优化,加了一个标志位,如果上一次循环未发生交换,就说明已经是有序的了,就不继续下去了,反之继续进行下一轮。

本文的图片来源网络,仅用于大家学习,侵权联系删除!(下同)

完整代码:

package com.keafmd.Sequence;

/**
 * Keafmd
 *
 * @ClassName: BubbleSort
 * @Description: 冒泡排序
 * @author: 牛哄哄的柯南
 * @date: 2021-06-24 10:31
 */
public class BubbleSort {

//冒泡排序
    public static void bubbleSort(int[] arr, boolean ascending) { //exchange标志表示为升序排序还是降序排序

boolean flag = true; //加一个标志位,记录上一次是否发生了交换,如果是,我们则进行下一轮,如果没有,说明已经冒泡好了

for (int i = 1; i < arr.length && flag; i++) { //控制次数,第几趟排序,只需要n-1趟,有交换时进行,只有flag=false就说明上一次一个元素都没有进行交换

/*System.out.print("第"+i+"次遍历:");
            for (int i1 : arr) {
                System.out.print(i1+" ");
            }
            System.out.println();*/

flag = false; //假定未交换

for (int j = 0; j < arr.length - i; j++) {

if (ascending ? arr[j] > arr[j + 1] : arr[j] < arr[j + 1]) { //控制升序还是降序
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = true;
                }

}
        }
    }

//冒泡排序 -- 默认不传参升序
    public static void bubbleSort(int[] arr) {
        bubbleSort(arr, true);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
测试代码:

升序排序(从小到大)

package com.keafmd.Sequence;

import java.util.*;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * Keafmd
 *
 * @ClassName: Sort
 * @Description: 十大排序算法
 * @author: 牛哄哄的柯南
 * @date: 2021-06-16 21:27
 */
public class Sort {
    public static void main(String[] args) {

int[] nums = {12, 4, 25, 47, 58, 34, 25, 9, 99, 26, 1, -13, 162, 10093, -66, -1};
        int[] temparr;

//测试冒泡排序
        System.out.println("测试冒泡排序:");
        temparr = nums.clone();
        BubbleSort.bubbleSort(temparr);
        //逆序排序
        //BubbleSort.bubbleSort(temparr,false);
        for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
运行结果:

测试冒泡排序:
-66 -13 -1 1 4 9 12 25 25 26 34 47 58 99 162 10093 
1
2
降序排序(从大到小)

//测试冒泡排序
System.out.println("测试冒泡排序:");
temparr = nums.clone();
BubbleSort.bubbleSort(temparr,false);
for (int i = 0; i < temparr.length; i++) {
    System.out.print(temparr[i] + " ");
}
System.out.println();
1
2
3
4
5
6
7
8
运行结果:

测试冒泡排序:
10093 162 99 58 47 34 26 25 25 12 9 4 1 -1 -13 -66 
1
2
下面几个算法的测试也就是换了下类名和方法名(换成相应的排序算法),如果想降序就在数组后面传个false即可。我就不一一复制了,我在最下面给出含所有算法的测试类,需要的自取即可。

快速排序
简单解释:
快速排序就是每次找一个基点(第一个元素),然后两个哨兵,一个从最前面往后走,一个从最后面往前面走,如果后面那个哨兵找到了一个比基点大的数停下来,前面那个哨兵找到比基点大的数停下来,然后交换两个哨兵找到的数,如果找不到最后两个哨兵就会碰到一起就结束,最后交换基点和哨兵相遇的地方的元素,然后就将一个序列分为比基点小的一部分和比基点大的一部分,然后递归左半部分和右半部分,最后的结果就是有序的了。

完整代码:

package com.keafmd.Sequence;

/**
 * Keafmd
 *
 * @ClassName: QuickSort
 * @Description: 快速排序
 * @author: 牛哄哄的柯南
 * @date: 2021-06-24 10:32
 */
public class QuickSort {

//快速排序
    public static void quickSort(int[] arr) {
        quickSort(arr, true);
    }

public static void quickSort(int[] arr, boolean ascending) {
        if (ascending) {
            quickSort(arr, 0, arr.length - 1, true);
        } else {
            quickSort(arr, 0, arr.length - 1, false);
        }
    }

public static void quickSort(int[] arr, int begin, int end, boolean ascending) {
        if (ascending)
            quickSort(arr, begin, end);
        else
            quickSortDescending(arr, begin, end);
    }

//快排序升序 -- 默认
    public static void quickSort(int[] arr, int begin, int end) {
        if (begin > end) { //结束条件
            return;
        }
        int base = arr[begin];
        int i = begin, j = end;
        while (i < j) { // 两个哨兵(i左边,j右边)没有相遇
            while (arr[j] >= base && i < j) { //哨兵j没找到比base小的
                j--;
            }
            while (arr[i] <= base && i < j) { //哨兵i没找到比base大的
                i++;
            }
            if (i < j) { //如果满足条件则交换
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }

}
        //最后将基准为与i和j相等位置的数字交换
        arr[begin] = arr[i];
        arr[i] = base;
        quickSort(arr, begin, i - 1); //递归调用左半数组
        quickSort(arr, i + 1, end); //递归调用右半数组

}

//快排序降序
    public static void quickSortDescending(int[] arr, int begin, int end) {
        if (begin > end) { //结束条件
            return;
        }
        int base = arr[begin];
        int i = begin, j = end;
        while (i < j) { // 两个哨兵(i左边,j右边)没有相遇
            while (arr[j] <= base && i < j) { //哨兵j没找到比base大的
                j--;
            }
            while (arr[i] >= base && i < j) { //哨兵i没找到比base小的
                i++;
            }
            if (i < j) { //如果满足条件则交换
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }

}
        //最后将基准为与i和j相等位置的数字交换
        arr[begin] = arr[i];
        arr[i] = base;
        quickSortDescending(arr, begin, i - 1); //递归调用左半数组
        quickSortDescending(arr, i + 1, end); //递归调用右半数组

}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
直接选择排序
简单解释:
数组分为已排序部分(前面)和待排序序列(后面)
第一次肯定所有的数都是待排序的
从待排序的序列中找到最大或最小的那个元素,放到前面的已排序部分,然后一直找,不断缩小待排序的范围,直到所有的数都是已排序的了

完整代码:

package com.keafmd.Sequence;

/**
 * Keafmd
 *
 * @ClassName: SelectSort
 * @Description: 选择排序
 * @author: 牛哄哄的柯南
 * @date: 2021-06-24 10:33
 */
public class SelectSort {

//直接选择排序
    public static void selectSort(int[] arr, boolean ascending) {
        for (int i = 0; i < arr.length; i++) {
            int m = i; //最小值或最小值的下标
            for (int j = i + 1; j < arr.length; j++) {
                if (ascending ? arr[j] < arr[m] : arr[j] > arr[m]) {
                    m = j; //找到待排序的数中最小或最大的那个数,记录下标
                }

}
            //交换位置
            int temp = arr[i];
            arr[i] = arr[m];
            arr[m] = temp;

}
    }

public static void selectSort(int[] arr) {
        selectSort(arr, true);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
堆排序
先理解下大顶堆和小顶堆,看图
大顶堆,双亲结点的值比每一个孩子结点的值都要大。根结点值最大
小顶堆,双亲结点的值比每一个孩子结点的值都要小。根结点值最小

简单解释:
构建好大顶堆或小顶堆结构,这样最上面的就是最大值或最小值,那么我们取出堆顶元素,然后重新构建结构,一直取,一直重新构建,那么最后达到排序的效果了。

完整代码:

package com.keafmd.Sequence;

/**
 * Keafmd
 *
 * @ClassName: HeapSort
 * @Description: 堆排序
 * @author: 牛哄哄的柯南
 * @date: 2021-06-24 10:34
 */
public class HeapSort {

//堆排序
    public static void heapSort(int[] arr) {
        //对传入的数组进行建立堆,这里默认建立大顶堆,进行升序排列
        heapSort(arr, true);
    }

public static void heapSort(int[] arr, boolean maxheap) {

//1.构建大顶堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            //从第一个非叶子结点从下至上,从右至左调整结构
            sift(arr, i, arr.length , maxheap);
        }

//2.调整堆结构+交换堆顶元素与末尾元素
        for (int j = arr.length - 1; j > 0; j--) {

//现在的数组第一个就是根结点,最小值所在,进行交换,把它放到最右边
            int temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;

//重新建立堆
            sift(arr, 0, j , maxheap); //重新对堆进行调整
        }
    }

//建立堆的方法
    /**
     * 私有方法,只允许被堆排序调用
     *
     * @param arr     要排序数组
     * @param parent  当前的双亲节点
     * @param len     数组长度
     * @param maxheap 是否建立大顶堆
     */
    private static void sift(int[] arr, int parent, int len, boolean maxheap) {

int value = arr[parent]; //先取出当前元素i

for (int child = 2 * parent + 1; child < len; child = child * 2 + 1) { //从parent结点的左子结点开始,也就是2*parent+1处开始

if (child+1 < len && (maxheap ? arr[child] < arr[child + 1] : arr[child] > arr[child + 1])) { //如果左子结点小于右子结点,child指向右子结点
                child++; //右孩子如果比左孩子大,我们就将现在的孩子换到右孩子
            }

//判断是否符合大顶堆的特性, 如果右孩子大于双亲,自然左孩子也大于双亲,符合
            //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
            if (maxheap ? value < arr[child] : value > arr[child]) {
                arr[parent]=arr[child];
                parent = child;
            }
            else {//如果不是,说明已经符合我们的要求了。
                break;
            }
        }
        arr[parent] =value; //将value值放到最终的位置

}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
归并排序
简单解释:
该算法是采用分治法,把数组不断分割,直至成为单个元素,然后比较再合并(合并的过程就是两部分分别从头开始比较,取出最小或最大元素的放到新的区域内,继续取两部分中最大或最小的元素,直到这两部分合并完,最后所有的都合并完,最后形成完整的有序序列)

完整代码:

package com.keafmd.Sequence;

/**
 * Keafmd
 *
 * @ClassName: MergeSort
 * @Description: 归并排序
 * @author: 牛哄哄的柯南
 * @date: 2021-06-24 10:35
 */
public class MergeSort {

//归并排序
    public static void mergeSort(int []arr ,boolean ascending){
        int[] temp = new int[arr.length]; //在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
        mergeSort(arr,0,arr.length-1,temp,ascending);
    }
    public static void mergeSort(int []arr){
        mergeSort(arr,true);
    }

/**
     *
     * @param arr 传入的数组
     * @param left 当前子数组的起始下标
     * @param right 当前子数组的结束下标
     * @param temp 拷贝暂存数组
     */
    public static void mergeSort(int []arr,int left,int right,int[] temp,boolean ascending){
        if(left

//对半分,比如总长度是10,left=0,right=9,mid=4确实是中间分了,0~4,5~9
            //当长度9,left=0,right=8,mid=4,0~4,5~8
            int mid = left + (right-left)/2; // 防止越界的写法
            //int mid = (left+right)/2;

mergeSort(arr,left,mid,temp,ascending); //左边归并排序,使得左子序列有序
            mergeSort(arr,mid+1,right,temp,ascending); //右边归并排序,使得右子序列有序

merge(arr,left,mid,right,temp,ascending); //将两个有序子数组合并操作
        }
    }

private static void merge(int[] arr,int left,int mid,int right,int[] temp,boolean ascending){
        int i = left; //左序列起始下标
        int j = mid+1; //右序列起始下标
        int t = 0; //临时数组指针
        while(i<=mid&&j<=right){
            if(ascending?arr[i]arr[j]){ //比较两个序列第一个元素谁小,谁小先拷贝谁到temp,然后对应子序列下标加1
                temp[t++] = arr[i++];
            }else {
                temp[t++] = arr[j++];
            }
        }

while(i<=mid){ //将左边剩余元素填充进temp中——左序列有一些数总是比右边的大的数
            temp[t++] = arr[i++];
        }

while(j<=right){ //将右序列剩余元素填充进temp中——右序列有一些数总是比左边的大的数
            temp[t++] = arr[j++];
        }

t = 0;

//将temp中的元素全部拷贝到原数组中
        while(left<=right){
            arr[left++] = temp[t++];
        }

}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
插入排序
简单解释:
最简单的理解就是打地主时我们拿到牌后的整理过程,从第二个牌(假设我们拿起来这个牌开始比较)开始,(说下升序)从后往前比较如果比前面的那个牌小,就把牌往后移动,直到找到一个合适的位置(这个位置的前面的那个牌不比这个要放下的牌大)就把这个牌放到这个位置,慢慢的前面的部分变得有序,直至全部有序即可。

完整代码:

package com.keafmd.Sequence;

/**
 * Keafmd
 *
 * @ClassName: StraghtInsertSort
 * @Description: 插入排序
 * @author: 牛哄哄的柯南
 * @date: 2021-06-24 10:36
 */
public class StraghtInsertSort {
    //插入排序
    public static void straghtInsertSort(int[] arr) {
        straghtInsertSort(arr, true);//默认进行升序
    }

public static void straghtInsertSort(int[] arr, boolean ascending) {

for (int i = 1; i < arr.length; i++) {
            int temp = arr[i];
            int j=0; //这就是那个合适的位置
            for (j = i - 1; j >= 0 && (ascending ? temp < arr[j] : temp > arr[j]); j--) {
                arr[j + 1] = arr[j];
            }
            //把牌放下,为啥是j+1,
            //是因为上面的循环遍历到不符合情况的时候 j是合适的位置的前面的那个数的位置
            //有点拗口,但是就是这个意思,看图方便理解下
            arr[j + 1] = temp;

}

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
希尔排序
简单解释:
希尔排序是插入排序的改进版,我们理解一个叫做下标差的的东西,也就是下面那个图中的增量d,初始下标差为arr.length/2,然后继续/2,对在同一下标差(相当于把这几个数单独拿出来了)的若干个数进行插入排序即可。

完整代码:

package com.keafmd.Sequence;

/**
 * Keafmd
 *
 * @ClassName: ShellSort
 * @Description: 希尔排序
 * @author: 牛哄哄的柯南
 * @date: 2021-06-24 10:39
 */
public class ShellSort {

public static void shellSort(int[] arr) {
        shellSort(arr,true);
    }

public static void shellSort(int[] arr,boolean ascending) {

for(int d = arr.length/2;d>0;d/=2){

for(int i=d;i< arr.length;i++){
                int temp = arr[i];
                int j=0;
                for(j=i-d;j>=0&&(ascending?temparr[j]);j-=d){
                    arr[j+d]=arr[j];
                }
                arr[j+d] = temp;
            }
        }

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
计数排序
简单解释:
这个排序算法看名字也很好理解,就是就是额外找个数组来计数,然后在这个数组从小到大或从大到小把数取出来即可。

完整代码:

package com.keafmd.Sequence;

/**
 * Keafmd
 *
 * @ClassName: CountSort
 * @Description: 计数排序
 * @author: 牛哄哄的柯南
 * @date: 2021-06-24 11:31
 */
public class CountSort {

public static void countSort(int[]arr){
        countSort(arr,true);
    }

public static void countSort(int[]arr,boolean ascending){
        int d,min=arr[0],max=arr[0];

//找出最大、最小值
        for(int i=0;i< arr.length;i++){
            if(arr[i]                 min =arr[i];
            }
            if(arr[i]>max){
                max = arr[i];
            }
        }

//建立一个用于计数的数组
        d = min;
        int[] count_map = new int[max-min+1];
        for(int i=0;i< arr.length;i++){
            count_map[arr[i]-d]++;
        }

int k =0;
        if(ascending){
            for(int i=0;i< arr.length;){
                if(count_map[k]>0){
                    arr[i] = k+d;
                    i++;
                    count_map[k]--;
                }else
                    k++;
            }
        }else {
            for(int i=arr.length-1;i>=0;){
                if(count_map[k]>0){
                    arr[i] = k+d;
                    i--;
                    count_map[k]--;
                }else
                    k++;
            }
        }

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
桶排序
简单解释:
就是把一个数组分成几个桶(其实是几个区间,从小到大或从大到小的几个区间)装,然后让每个桶(区间)有序,然后取出来放一起就可以了,相当于把几个有序的段拿出来放一起,自然还是有序的,当然需要是按照区间的顺序拿了。

完整代码:

package com.keafmd.Sequence;

import java.util.ArrayList;
import java.util.Collections;

/**
 * Keafmd
 *
 * @ClassName: BucketSort
 * @Description: 桶排序
 * @author: 牛哄哄的柯南
 * @date: 2021-06-24 13:32
 */
public class BucketSort {

public static void bucketSort(int[] arr){
        bucketSort(arr,true);
    }

public static void bucketSort(int[] arr,boolean ascending){
        if(arr==null||arr.length==0){
            return;
        }
        //计算最大值与最小值
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for(int i=0;i             max = Math.max(arr[i],max);
            min = Math.min(arr[i],min);
        }

//计算桶的数量
        int bucketNUm = (max-min)/ arr.length+1;
        ArrayList> bucketArr = new ArrayList<>(bucketNUm);
        for(int i=0;i             bucketArr.add(new ArrayList<>());
        }

//将每个元素放入桶中
        for(int i=0;i             int num = (arr[i]-min)/ (arr.length);
            bucketArr.get(num).add(arr[i]);
        }

//对每个桶进行排序
        for (int i = 0; i < bucketArr.size(); i++) {
            //用系统的排序,速度肯定没话说
            Collections.sort(bucketArr.get(i));
        }

//将桶中元素赋值到原序列
        int index;
        if(ascending){
            index=0;
        }else{
            index=arr.length-1;
        }

for(int i=0;i             for(int j= 0;j                 arr[index] = bucketArr.get(i).get(j);
                if(ascending){
                    index++;
                }else{
                    index--;
                }
            }

}

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
基数排序
简单解释:
首先说一下,我发现好多人写的基数排序只能排序正整数,其实只要处理下就可以排序含有负数的了,就是我们排序前先把所有的数整体变大(就是减上最小的负数,也就是加了),都变成正数,然后排序好之后,在减下来(加上最小的负数,也就减了)就好了。
基数排序就是按数位排序可分为LSD(从最低位[也就是个位]开始排序)和MSD(从最高位开始排序),下面写的事LSD基数排序。
基数排序就是把数按位考虑,让后我们一位数只能是[0,9],就是我们在考虑某位(个位、百位· · ·)的时候就只看这个位的数,放到在[0,9]相应的位置,然后顺序取出,最后再按其它位这样操作(上面说了要不从低位开始到高位,要不就是从高位到低位)

完整代码:

package com.keafmd.Sequence;

/**
 * Keafmd
 *
 * @ClassName: RadixSort
 * @Description: 基数排序
 * @author: 牛哄哄的柯南
 * @date: 2021-06-24 14:32
 */
public class RadixSort {
    public static void radixSort(int[] arr){
        radixSort(arr,true);
    }
    public static void radixSort(int[]arr,boolean ascending){
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        //求出最大值、最小值
        for (int i = 0; i < arr.length; i++) {
            max = Math.max(max, arr[i]);
            min = Math.min(min, arr[i]);
        }
        if (min<0) {    //如果最小值小于0,那么把每个数都减去最小值,这样可以保证最小的数是0
            for (int i = 0; i < arr.length; i++) {
                arr[i] -= min;
            }
            max -= min; //max也要处理!
        }
        //很巧妙求出最大的数有多少位
        int maxLength = (max+"").length();
        int[][] bucket = new int[10][arr.length]; //一个二维数组,一维代表0到9,二维存放符合数
        int[] bucketElementCount = new int[10]; // 用于记录0到9某位存在数字的个数
        for (int i = 0 ,n = 1 ; i < maxLength ; i++,n*=10) { //个位 十位 百位 这样遍历
            for (int j = 0; j < arr.length ; j++) {
                int value = arr[j]/n % 10;
                bucket[value][bucketElementCount[value]] = arr[j];
                bucketElementCount[value]++;
            }

//升序
            if(ascending) {
                int index = 0;
                //从左到右,从下到上取出每个数
                for (int j = 0; j < bucketElementCount.length; j++) {
                    if (bucketElementCount[j] != 0) {
                        for (int k = 0; k < bucketElementCount[j]; k++) {
                            arr[index] = bucket[j][k];
                            index++;
                        }
                    }
                    bucketElementCount[j] = 0;
                }
            }else { // 降序
                int index=0;
                //从右到左,从下到上取出每个数
                for (int j = bucketElementCount.length-1; j >=0; j--) {
                    if (bucketElementCount[j] != 0) {
                        for (int k = 0; k                             arr[index] = bucket[j][k];
                            index++;
                        }
                    }
                    bucketElementCount[j] = 0;
                }
            }

/*for (int i1 = 0; i1 < arr.length; i1++) {
                System.out.print(arr[i1]+" ");
            }
            System.out.println();*/

}
        if (min<0){
            for (int i = 0; i < arr.length ; i++) {
                arr[i] += min;
            }
        }

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
完整测试类
package com.keafmd.Sequence;

import java.util.*;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * Keafmd
 *
 * @ClassName: Sort
 * @Description: 十大排序算法测试类
 * @author: 牛哄哄的柯南
 * @date: 2021-06-16 21:27
 */
public class Sort {

public static void main(String[] args) {

int[] nums = {12, 4, 25, 47, 58, 34, 25, 9, 99, 26, 1, -13, 162, 10093, -66, -1};
//        int[] nums = {12, 43,56,42,26,11};
        int[] temparr;

//利用系统Collections.sort方法进行对比

//将int数组转换为Integer数组
        //1、先将int数组转换为数值流
        temparr = nums.clone();
        IntStream stream = Arrays.stream(temparr);
        //2、流中的元素全部装箱,转换为流 ---->int转为Integer
        Stream integerStream = stream.boxed();
        //3、将流转换为数组
        Integer[] integers = integerStream.toArray(Integer[]::new);
        //把数组转为List
        List tempList = new ArrayList<>(Arrays.asList(integers));
        //使用Collections.sort()排序
        System.out.println("使用系统的Collections.sort()的对比:");

//Collections.sort
        Collections.sort(tempList, new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1-o2;
                //return o2-o1;
            }
        });

//tempList.sort 也可以排序
       /* tempList.sort(new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                //return o1-o2;
                return o2-o1;
            }
        });*/

//遍历输出结果
        for (Integer integer : tempList) {
            System.out.print(integer+" ");
        }

System.out.println();

//测试冒泡排序
        System.out.println("测试冒泡排序:");
        temparr = nums.clone();

BubbleSort.bubbleSort(temparr);

//降序
        //BubbleSort.bubbleSort(temparr,false);

for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

//测试快速排序
        System.out.println("测试快速排序:");
        temparr = nums.clone();
        QuickSort.quickSort(temparr);
        //QuickSort.quickSort(temparr,false);
        for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

//测试直接选择排序
        System.out.println("测试直接选择排序:");
        temparr = nums.clone();
        SelectSort.selectSort(temparr);
        //SelectSort.selectSort(temparr,false);
        for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

//测试堆排序
        System.out.println("测试堆排序:");
        temparr = nums.clone();
        HeapSort.heapSort(temparr);
        //HeapSort.heapSort(temparr,false);
        for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

//测试归并排序
        System.out.println("测试归并排序:");
        temparr = nums.clone();
        MergeSort.mergeSort(temparr);
        //MergeSort.mergeSort(temparr,false);
        for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

//测试插入排序
        System.out.println("测试插入排序:");
        temparr = nums.clone();
        StraghtInsertSort.straghtInsertSort(temparr);
        //StraghtInsertSort.straghtInsertSort(temparr,false);
        for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

//测试希尔排序
        System.out.println("测试希尔排序:");
        temparr = nums.clone();
        ShellSort.shellSort(temparr);
        //ShellSort.shellSort(temparr,false);
        for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

//测试计数排序
        System.out.println("测试计数排序:");
        temparr = nums.clone();
        CountSort.countSort(temparr);
        //CountSort.countSort(temparr,false);
        for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

//测试桶排序
        System.out.println("测试桶排序:");
        temparr = nums.clone();
        BucketSort.bucketSort(temparr);
        //BucketSort.bucketSort(temparr,false);
        for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

//测试基数排序
        System.out.println("测试基数排序:");
        temparr = nums.clone();
        RadixSort.radixSort(temparr);
        //RadixSort.radixSort(temparr,false);
        for (int i = 0; i < temparr.length; i++) {
            System.out.print(temparr[i] + " ");
        }
        System.out.println();

}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
每天进步一点点!
不进则退!

版权声明:
原创博主:牛哄哄的柯南
博主原文链接:https://keafmd.blog.csdn.net/

看完如果对你有帮助,感谢点赞支持!
如果你是电脑端,看到右下角的 “一键三连” 了吗,没错点它[哈哈]

加油!

共同努力!

Keafmd
————————————————
版权声明:本文为CSDN博主「牛哄哄的柯南」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43883917/article/details/118193663

经典十大排序算法(含升序降序,基数排序含负数排序)【Java版完整代码】【建议收藏系列】相关推荐

  1. java treemap value排序_Java TreeMap升序|降序排列和按照value进行排序的案例

    TreeMap 升序|降序排列 import java.util.Comparator; import java.util.TreeMap; public class Main { public st ...

  2. Vue升序降序(前端价格排序)

    定义两个按钮 <div id="showGoods"><button @click="upchange">升序</button&g ...

  3. 一点就懂的经典十大排序算法

    文章目录 1.概述 2.十大算法性能比较 3.排序算法精讲 3.1 超级经典的排序--冒泡排序和它的优化 3.2 最常用的排序--快速排序(基准值分段,交换,分而治之,递归实现) 3.3 最简单直接的 ...

  4. 数据挖掘经典十大算法_对基本概念的理解

    数据挖掘经典十大算法 一.十大经典算法 二.信息量 信息量是对信息的度量,例如时间的度量是秒,我们考虑一个离散的随机变量x时,当我们观察到的这个变量的一个具体值的时候,我们接收到的多少信息 用信息量来 ...

  5. 数据挖掘经典十大算法_K-Means算法

    数据挖掘经典十大算法_K-Means算法 一.从故事理解K-Means Clustering Algorithm 1.有四个牧师去郊区布道,一开始牧师们随意选了几个布道点,并且把这几个布道点的情况公告 ...

  6. 机器学习系列(二)ML经典十大算法之一:决策树算法--从代码和统计学角度谈谈cs是如何预测你的行为

    写在前面: 我是「nicedays」,一枚喜爱做特效,听音乐,分享技术的大数据开发猿.这名字是来自world order乐队的一首HAVE A NICE DAY.如今,走到现在很多坎坷和不顺,如今终于 ...

  7. 十大编程算法助程序员走上大神路

    概述:编程算法,是完成程序逻辑的主要途径.本文推荐十大编程算法,有利于程序员的编程逻辑. 算法一:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n lo ...

  8. python中升序降序问题_飘逸的python - 有的升序有的降序的情况下怎么多条件排序...

    之前在统计导出各区服玩家消费的时候需要进行升序降序混搭的多条件排序. 需求是这样的.区服从小到大排,如果区服相同,则按消费从大到小排. 实现方法是利用python的sort算法是稳定排序,对数据进行多 ...

  9. 冒泡算法 升序 降序

    php中其实已经实现了基本的冒泡算法 升序降序等等:对数组进行排序 下面参考:冒泡排序法原理讲解及PHP代码示例 - 温柔的风 - 博客园 手动实现: <?php //从小到大排序 functi ...

最新文章

  1. java语言中解释方式是什么意思,Java语言快速入门·简答T
  2. java Dated Dateformat Calendar
  3. SGML、HTML和XML之间的关系
  4. 鼠标移动到div上,div中的img放大
  5. myeclipse搭建php,MyEclipse配置JDK类库的简易流程
  6. C#创建Access
  7. 腾讯,字节,阿里,小米,京东大厂Offer拿到手软!分享一点面试小经验
  8. python 捕获鼠标点击事件,在Python中的wx.Frame外部捕获鼠标事件
  9. Symfony1.4.11学习笔记(三):设置虚拟机
  10. vue放大缩小div_vue 放大缩小 svg 图形(原理类似整个列表更新)
  11. 大数据_Flink_数据处理_命令行提交Job---Flink工作笔记0014
  12. http://localhost:9000/application.pac问题解决!
  13. 让网站和APP更具动感的几点建议
  14. C++基础:造成多态性的原因是什么?
  15. MATLAB教程(二)matlib安装
  16. 微信小程序引入iconfont阿里字体
  17. Java实现读取txt文件数据并导入数据库
  18. android 新浪微博第三方登录,Android的集成新浪微博第三方登录
  19. Gradle 2.0 用户指南翻译——第十九章. Gradle 守护进程
  20. 网关和路由器交换机功能的有哪些不同

热门文章

  1. 经典C语言程序100例之九八
  2. 电脑网络信号传输频率_高速数字电路设计中信号完整性
  3. 「C++」C++ Primer Plus 笔记:第三章 处理数据
  4. 「ImageProcess」mp4视频转存图片内存变大的原因探究
  5. android:background=@color/white [create file color.xml at res/values/]
  6. 怎么查看计算机一共多少文档,不打开Word文档如何查看文章有几页 -电脑资料
  7. 太吾绘卷存档修改2020_太吾绘卷/神级初始存档
  8. python模拟火车订票系统_如何用python编写火车抢票助手
  9. 导致溢出_1篇文章搞清楚8种JVM内存溢出(OOM)的原因和解决方法
  10. Python操作MySQL数据库的三种方法