十大排序算法可以说是每个程序员都必须得掌握的了,花了一天的时间把代码实现且整理了一下,为了方便大家学习,我把它整理成一篇文章,每种算法会有简单的算法思想描述,为了方便大家理解,我还找来了动图演示;这还不够,我还附上了对应的优质文章,看完不懂你来砍我,如果不想砍我就给我来个好看

术语铺垫

有些人可能不知道什么是稳定排序、原地排序、时间复杂度、空间复杂度,我这里先简单解释一下:

1、稳定排序:如果 a 原本在 b 的前面,且 a == b,排序之后 a 仍然在 b 的前面,则为稳定排序。

2、非稳定排序:如果 a 原本在 b 的前面,且 a == b,排序之后 a 可能不在 b 的前面,则为非稳定排序。

3、原地排序:原地排序就是指在排序过程中不申请多余的存储空间,只利用原来存储待排数据的存储空间进行比较和交换的数据排序。

4、非原地排序:需要利用额外的数组来辅助排序。

5、时间复杂度:一个算法执行所消耗的时间。

6、空间复杂度:运行完一个算法所需的内存大小。

十大排序讲解顺序

为了方便大家查找,我这里弄一个伪目录,没有跳转功能。

  • 选择排序

  • 插入排序

  • 冒泡排序

    • 非优化版本

    • 优化版本

  • 希尔排序

  • 归并排序

    • 递归式归并排序

    • 非递归式归并排序

  • 快速排序

  • 堆排序

  • 基数排序

    • 非优化版本

    • 优化版本

  • 桶排序

  • 基数排序

另:

代码说明:代码我自己写的,并且都是经过好几组数据测试通过,应该没啥问题,如有错,还请反馈下,谢谢。

图片说明:图片和动画都是在百度搜索的,如有侵权,还望联系我删除,谢谢

1、选择排序

过程简单描述:
首先,找到数组中最小的那个元素,其次,将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)。其次,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。这种方法我们称之为选择排序

为方便理解我还准备了动图:

如果还是不懂的话我还给你准备了优质的文章讲解:选择排序

代码如下(代码片可以左右拉动,下同):

 1public class SelectSort {
2    public static int[] selectSort(int[] a) {
3        int n = a.length;
4        for (int i = 0; i < n - 1; i++) {
5            int min = i;
6            for (int j = i + 1; j < n; j++) {
7                if(a[min] > a[j]) min = j;
8            }
9            //交换
10            int temp = a[i];
11            a[i] = a[min];
12            a[min] = temp;
13        }
14        return a;
15    }
16}

性质:1、时间复杂度:O(n2)  2、空间复杂度:O(1)  3、非稳定排序  4、原地排序

2、插入排序

我们在玩打牌的时候,你是怎么整理那些牌的呢?一种简单的方法就是一张一张的来,将每一张牌插入到其他已经有序的牌中的适当位置。当我们给无序数组做排序的时候,为了要插入元素,我们需要腾出空间,将其余所有元素在插入之前都向右移动一位,这种算法我们称之为插入排序

过程简单描述:

1、从数组第2个元素开始抽取元素。

2、把它与左边第一个元素比较,如果左边第一个元素比它大,则继续与左边第二个元素比较下去,直到遇到不比它大的元素,然后插到这个元素的右边。

3、继续选取第3,4,….n个元素,重复步骤 2 ,选择适当的位置插入。

为方便理解我还准备了动图:

如果还是不懂的话我还给你准备了优质的文章讲解:插入排序

代码如下:

 1public class InsertSort {
2    public static int[] insertSort(int[] arr) {
3        if(arr == null || arr.length < 2)
4            return arr;
5
6        int n = arr.length;
7        for (int i = 1; i < n; i++) {
8            int temp = arr[i];
9            int k = i - 1;
10            while(k >= 0 && arr[k] > temp)
11                k--;
12            //腾出位置插进去,要插的位置是 k + 1;
13            for(int j = i ; j > k + 1; j--)
14                arr[j] = arr[j-1];
15            //插进去
16            arr[k+1] = temp;
17        }
18        return arr;
19    }
20}

性质:1、时间复杂度:O(n2)  2、空间复杂度:O(1)  3、稳定排序  4、原地排序

3、冒泡排序

1、把第一个元素与第二个元素比较,如果第一个比第二个大,则交换他们的位置。接着继续比较第二个与第三个元素,如果第二个比第三个大,则交换他们的位置….

我们对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样一趟比较交换下来之后,排在最右的元素就会是最大的数。

除去最右的元素,我们对剩余的元素做同样的工作,如此重复下去,直到排序完成。

为方便理解我还准备了动图:

如果还是不懂的话我还给你准备了优质的文章讲解:冒泡排序

代码如下

 1public class BubbleSort {
2    public static int[] bubbleSort(int[] arr) {
3        if (arr == null || arr.length < 2) {
4            return arr;
5        }
6        int n = arr.length;
7        for (int i = 0; i < n; i++) {
8            for (int j = 0; j < n -i - 1; j++) {
9                if (arr[j + 1] < arr[j]) {
10                    int t = arr[j];
11                    arr[j] = arr[j+1];
12                    arr[j+1] = t;
13                }
14            }
15        }
16        return arr;
17    }
18)

性质:1、时间复杂度:O(n2)  2、空间复杂度:O(1)  3、稳定排序  4、原地排序

优化一下冒泡排序的算法

假如从开始的第一对到结尾的最后一对,相邻的元素之间都没有发生交换的操作,这意味着右边的元素总是大于等于左边的元素,此时的数组已经是有序的了,我们无需再对剩余的元素重复比较下去了。

代码如下:

 1public class BubbleSort {
2    public static int[] bubbleSort(int[] arr) {
3        if (arr == null || arr.length < 2) {
4            return arr;
5        }
6        int n = arr.length;
7        for (int i = 0; i < n; i++) {
8            boolean flag = true;
9            for (int j = 0; j < n -i - 1; j++) {
10                if (arr[j + 1] < arr[j]) {
11                    flag = false;
12                    int t = arr[j];
13                    arr[j] = arr[j+1];
14                    arr[j+1] = t;
15                }
16            }
17            //一趟下来是否发生位置交换
18            if(false)
19                break;
20        }
21        return arr;
22    }
23}

4、希尔排序

希尔排序可以说是插入排序的一种变种。无论是插入排序还是冒泡排序,如果数组的最大值刚好是在第一位,要将它挪到正确的位置就需要 n - 1 次移动。也就是说,原数组的一个元素如果距离它正确的位置很远的话,则需要与相邻元素交换很多次才能到达正确的位置,这样是相对比较花时间了。

希尔排序就是为了加快速度简单地改进了插入排序,交换不相邻的元素以对数组的局部进行排序。

希尔排序的思想是采用插入排序的方法,先让数组中任意间隔为 h 的元素有序,刚开始 h 的大小可以是 h = n / 2,接着让 h = n / 4,让 h 一直缩小,当 h = 1 时,也就是此时数组中任意间隔为1的元素有序,此时的数组就是有序的了。

为方便理解我还准备了图片:

如果还是不懂的话我还给你准备了优质的文章讲解:希尔排序

代码如下

 1public class ShellSort {
2    public static int[] shellSort(int arr[]) {
3        if (arr == null || arr.length < 2) return arr;
4        int n = arr.length;
5        // 对每组间隔为 h的分组进行排序,刚开始 h = n / 2;
6        for (int h = n / 2; h > 0; h /= 2) {
7            //对各个局部分组进行插入排序
8            for (int i = h; i < n; i++) {
9                // 将arr[i] 插入到所在分组的正确位置上
10                insertI(arr, h, i);
11            }
12     }
13     return arr;
14    }
15
16    /**
17     * 将arr[i]插入到所在分组的正确位置上
18     * arr[i]] 所在的分组为 ... arr[i-2*h],arr[i-h], arr[i+h] ...
19     */
20    private static void insertI(int[] arr, int h, int i) {
21        int temp = arr[i];
22        int k;
23        for (k = i - h; k > 0 && temp < arr[k]; k -= h) {
24            arr[k + h] = arr[k];
25        }
26        arr[k + h] = temp;
27    }
28}

需要注意的是,对各个分组进行插入的时候并不是先对一个组排序完了再来对另一个组排序,而是轮流对每个组进行排序。

性质:1、时间复杂度:O(nlogn)  2、空间复杂度:O(1)  3、非稳定排序  4、原地排序

5、归并排序

将一个大的无序数组有序,我们可以把大的数组分成两个,然后对这两个数组分别进行排序,之后在把这两个数组合并成一个有序的数组。由于两个小的数组都是有序的,所以在合并的时候是很快的。

通过递归的方式将大的数组一直分割,直到数组的大小为 1,此时只有一个元素,那么该数组就是有序的了,之后再把两个数组大小为1的合并成一个大小为2的,再把两个大小为2的合并成4的 ….. 直到全部小的数组合并起来。

为方便理解我还准备了动图:

如果还是不懂的话我还给你准备了优质的文章讲解:归并排序

代码如下:

 1public class MergeSort {
2    // 归并排序
3    public static int[] mergeSort(int[] arr, int left, int right) {
4        // 如果 left == right,表示数组只有一个元素,则不用递归排序
5        if (left < right) {
6            // 把大的数组分隔成两个数组
7            int mid = (left + right) / 2;
8            // 对左半部分进行排序
9            arr = mergeSort(arr, left, mid);
10            // 对右半部分进行排序
11            arr = mergeSort(arr, mid + 1, right);
12            //进行合并
13            merge(arr, left, mid, right);
14        }
15        return arr;
16    }
17
18    // 合并函数,把两个有序的数组合并起来
19    // arr[left..mif]表示一个数组,arr[mid+1 .. right]表示一个数组
20    private static void merge(int[] arr, int left, int mid, int right) {
21        //先用一个临时数组把他们合并汇总起来
22        int[] a = new int[right - left + 1];
23        int i = left;
24        int j = mid + 1;
25        int k = 0;
26        while (i <= mid && j <= right) {
27            if (arr[i] < arr[j]) {
28                a[k++] = arr[i++];
29            } else {
30                a[k++] = arr[j++];
31            }
32        }
33        while(i <= mid) a[k++] = arr[i++];
34        while(j <= right) a[k++] = arr[j++];
35        // 把临时数组复制到原数组
36        for (i = 0; i < k; i++) {
37            arr[left++] = a[i];
38        }
39    }
40}

性质:1、时间复杂度:O(nlogn)  2、空间复杂度:O(n)  3、稳定排序  4、非原地排序

然而面试官要你写个非递归式的归并排序怎么办?别怕,我这还撸了个非递归式的归并排序,代码如下:

 1public class MergeSort {
2    // 非递归式的归并排序
3    public static int[] mergeSort(int[] arr) {
4        int n = arr.length;
5        // 子数组的大小分别为1,2,4,8...
6        // 刚开始合并的数组大小是1,接着是2,接着4....
7        for (int i = 1; i < n; i += i) {
8            //进行数组进行划分
9            int left = 0;
10            int mid = left + i - 1;
11            int right = mid + i;
12            //进行合并,对数组大小为 i 的数组进行两两合并
13            while (right < n) {
14                // 合并函数和递归式的合并函数一样
15                merge(arr, left, mid, right);
16                left = right + 1;
17                mid = left + i - 1;
18                right = mid + i;
19            }
20            // 还有一些被遗漏的数组没合并,千万别忘了
21            // 因为不可能每个字数组的大小都刚好为 i
22            if (left < n && mid < n) {
23                merge(arr, left, mid, n - 1);
24            }
25        }
26        return arr;
27    }
28}

6、快速排序

我们从数组中选择一个元素,我们把这个元素称之为中轴元素吧,然后把数组中所有小于中轴元素的元素放在其左边,所有大于或等于中轴元素的元素放在其右边,显然,此时中轴元素所处的位置的是有序的。也就是说,我们无需再移动中轴元素的位置。

从中轴元素那里开始把大的数组切割成两个小的数组(两个数组都不包含中轴元素),接着我们通过递归的方式,让中轴元素左边的数组和右边的数组也重复同样的操作,直到数组的大小为1,此时每个元素都处于有序的位置

为方便理解我还准备了动图:

如果还是不懂的话我还给你准备了优质的文章讲解:不要在问我快速排序

代码如下:

 1public class QuickSort {
2    public static int[] quickSort(int[] arr, int left, int right) {
3        if (left < right) {
4            //获取中轴元素所处的位置
5            int mid = partition(arr, left, right);
6            //进行分割
7            arr = quickSort(arr, left, mid - 1);
8            arr = quickSort(arr, mid + 1, right);
9        }
10        return arr;
11    }
12
13    private static int partition(int[] arr, int left, int right) {
14        //选取中轴元素
15        int pivot = arr[left];
16        int i = left + 1;
17        int j = right;
18        while (true) {
19            // 向右找到第一个小于等于 pivot 的元素位置
20            while (i <= j && arr[i] <= pivot) i++;
21            // 向左找到第一个大于等于 pivot 的元素位置
22            while(i <= j && arr[j] >= pivot ) j--;
23            if(i >= j)
24                break;
25            //交换两个元素的位置,使得左边的元素不大于pivot,右边的不小于pivot
26            int temp = arr[i];
27            arr[i] = arr[j];
28            arr[j] = temp;
29        }
30        arr[left] = arr[j];
31        // 使中轴元素处于有序的位置
32        arr[j] = pivot;
33        return j;
34    }
35}

性质:1、时间复杂度:O(nlogn)  2、空间复杂度:O(logn)  3、非稳定排序  4、原地排序

7、堆排序

堆的特点就是堆顶的元素是一个最值,大顶堆的堆顶是最大值,小顶堆则是最小值。

堆排序就是把堆顶的元素与最后一个元素交换,交换之后破坏了堆的特性,我们再把堆中剩余的元素再次构成一个大顶堆,然后再把堆顶元素与最后第二个元素交换….如此往复下去,等到剩余的元素只有一个的时候,此时的数组就是有序的了。

为方便理解我还准备了动图:

如果还是不懂的话我还给你准备了优质的文章讲解:堆排序是什么鬼?

代码如下:

 1public class Head {
2    // 堆排序
3    public static int[] headSort(int[] arr) {
4        int n = arr.length;
5        //构建大顶堆
6        for (int i = (n - 2) / 2; i >= 0; i--) {
7            downAdjust(arr, i, n - 1);
8        }
9        //进行堆排序
10        for (int i = n - 1; i >= 1; i--) {
11            // 把堆顶元素与最后一个元素交换
12            int temp = arr[i];
13            arr[i] = arr[0];
14            arr[0] = temp;
15            // 把打乱的堆进行调整,恢复堆的特性
16            downAdjust(arr, 0, i - 1);
17        }
18        return arr;
19    }
20
21        //下沉操作
22    public static void downAdjust(int[] arr, int parent, int n) {
23        //临时保存要下沉的元素
24        int temp = arr[parent];
25        //定位左孩子节点的位置
26        int child = 2 * parent + 1;
27        //开始下沉
28        while (child <= n) {
29            // 如果右孩子节点比左孩子大,则定位到右孩子
30            if(child + 1 <= n && arr[child] < arr[child + 1])
31                child++;
32            // 如果孩子节点小于或等于父节点,则下沉结束
33            if (arr[child] <= temp ) break;
34            // 父节点进行下沉
35            arr[parent] = arr[child];
36            parent = child;
37            child = 2 * parent + 1;
38        }
39        arr[parent] = temp;
40    }
41}

性质:1、时间复杂度:O(nlogn)  2、空间复杂度:O(1)  3、非稳定排序  4、原地排序

8、计数排序

计数排序是一种适合于最大值和最小值的差值不是不是很大的排序。

基本思想:就是把数组元素作为数组的下标,然后用一个临时数组统计该元素出现的次数,例如 temp[i] = m, 表示元素 i 一共出现了 m 次。最后再把临时数组统计的数据从小到大汇总起来,此时汇总起来是数据是有序的。

为方便理解我还准备了动图:

如果还是不懂的话我还给你准备了优质的文章讲解:什么是计数排序?

代码如下:

 1public class Counting {
2    public static int[] countSort(int[] arr) {
3        if(arr == null || arr.length < 2) return arr;
4
5        int n = arr.length;
6        int max = arr[0];
7        // 寻找数组的最大值
8        for (int i = 1; i < n; i++) {
9            if(max < arr[i])
10                max = arr[i];
11        }
12        //创建大小为max的临时数组
13        int[] temp = new int[max + 1];
14        //统计元素i出现的次数
15        for (int i = 0; i < n; i++) {
16            temp[arr[i]]++;
17        }
18        int k = 0;
19        //把临时数组统计好的数据汇总到原数组
20        for (int i = 0; i <= max; i++) {
21            for (int j = temp[i]; j > 0; j--) {
22                arr[k++] = i;
23            }
24        }
25        return arr;
26    }
27}

性质:1、时间复杂度:O(n+k)  2、空间复杂度:O(k)  3、稳定排序  4、非原地排序

注:K表示临时数组的大小,下同

优化一下

上面的代码中,我们是根据 max 的大小来创建对应大小的数组,假如原数组只有10个元素,并且最小值为 min = 10000,最大值为 max = 10005,那我们创建 10005 + 1 大小的数组不是很吃亏,最大值与最小值的差值为 5,所以我们创建大小为6的临时数组就可以了。

也就是说,我们创建的临时数组大小 (max - min + 1)就可以了,然后在把 min作为偏移量。优化之后的代码如下所示:

 1public class Counting {
2    public static int[] sort(int[] arr) {
3        if(arr == null || arr.length < 2) return arr;
4
5        int n = arr.length;
6        int min = arr[0];
7        int max = arr[0];
8        // 寻找数组的最大值与最小值
9        for (int i = 1; i < n; i++) {
10            if(max < arr[i])
11                max = arr[i];
12            if(min > arr[i])
13                min = arr[i];
14        }
15        int d = max - min + 1;
16        //创建大小为max的临时数组
17        int[] temp = new int[d];
18        //统计元素i出现的次数
19        for (int i = 0; i < n; i++) {
20            temp[arr[i] - min]++;
21        }
22        int k = 0;
23        //把临时数组统计好的数据汇总到原数组
24        for (int i = 0; i < d; i++) {
25            for (int j = temp[i]; j > 0; j--) {
26                arr[k++] = i + min;
27            }
28        }
29        return arr;
30    }
31}

9、桶排序

桶排序就是把最大值和最小值之间的数进行瓜分,例如分成  10 个区间,10个区间对应10个桶,我们把各元素放到对应区间的桶中去,再对每个桶中的数进行排序,可以采用归并排序,也可以采用快速排序之类的。

之后每个桶里面的数据就是有序的了,我们在进行合并汇总。

为方便理解我还准备了图片:

如果还是不懂的话我还给你准备了优质的文章讲解:什么是桶排序?

代码如下:

 1public class BucketSort {
2    public static int[] BucketSort(int[] arr) {
3        if(arr == null || arr.length < 2) return arr;
4
5        int n = arr.length;
6        int max = arr[0];
7        int min = arr[0];
8        // 寻找数组的最大值与最小值
9        for (int i = 1; i < n; i++) {
10            if(min > arr[i])
11                min = arr[i];
12            if(max < arr[i])
13                max = arr[i];
14        }
15        //和优化版本的计数排序一样,弄一个大小为 min 的偏移值
16        int d = max - min;
17        //创建 d / 5 + 1 个桶,第 i 桶存放  5*i ~ 5*i+5-1范围的数
18        int bucketNum = d / 5 + 1;
19        ArrayList<LinkedList<Integer>> bucketList = new ArrayList<>(bucketNum);
20        //初始化桶
21        for (int i = 0; i < bucketNum; i++) {
22            bucketList.add(new LinkedList<Integer>());
23        }
24        //遍历原数组,将每个元素放入桶中
25        for (int i = 0; i < n; i++) {
26            bucketList.get((arr[i]-min)/d).add(arr[i] - min);
27        }
28        //对桶内的元素进行排序,我这里采用系统自带的排序工具
29        for (int i = 0; i < bucketNum; i++) {
30            Collections.sort(bucketList.get(i));
31        }
32        //把每个桶排序好的数据进行合并汇总放回原数组
33        int k = 0;
34        for (int i = 0; i < bucketNum; i++) {
35            for (Integer t : bucketList.get(i)) {
36                arr[k++] = t + min;
37            }
38        }
39        return arr;
40    }
41}

性质:1、时间复杂度:O(n+k)  2、空间复杂度:O(n+k)  3、稳定排序  4、非原地排序

注:k 表示桶的个数,下同

10、基数排序

基数排序的排序思路是这样的:先以个位数的大小来对数据进行排序,接着以十位数的大小来多数进行排序,接着以百位数的大小……

排到最后,就是一组有序的元素了。不过,他在以某位数进行排序的时候,是用“桶”来排序的。

由于某位数(个位/十位….,不是一整个数)的大小范围为0-9,所以我们需要10个桶,然后把具有相同数值的数放进同一个桶里,之后再把桶里的数按照0号桶到9号桶的顺序取出来,这样一趟下来,按照某位数的排序就完成了

为方便理解我还准备了动图:

如果还是不懂的话我还给你准备了优质的文章讲解:为什么说O(n)复杂度的基数排序没有快速排序快?

代码如下:

 1public class RadioSort {
2
3    public static int[] radioSort(int[] arr) {
4        if(arr == null || arr.length < 2) return arr;
5
6        int n = arr.length;
7        int max = arr[0];
8        // 找出最大值
9        for (int i = 1; i < n; i++) {
10            if(max < arr[i]) max = arr[i];
11        }
12        // 计算最大值是几位数
13        int num = 1;
14        while (max / 10 > 0) {
15            num++;
16            max = max / 10;
17        }
18        // 创建10个桶
19        ArrayList<LinkedList<Integer>> bucketList = new ArrayList<>(10);
20        //初始化桶
21        for (int i = 0; i < 10; i++) {
22            bucketList.add(new LinkedList<Integer>());
23        }
24        // 进行每一趟的排序,从个位数开始排
25        for (int i = 1; i <= num; i++) {
26            for (int j = 0; j < n; j++) {
27                // 获取每个数最后第 i 位是数组
28                int radio = (arr[j] / (int)Math.pow(10,i-1)) % 10;
29                //放进对应的桶里
30                bucketList.get(radio).add(arr[j]);
31            }
32            //合并放回原数组
33            int k = 0;
34            for (int j = 0; j < 10; j++) {
35                for (Integer t : bucketList.get(j)) {
36                    arr[k++] = t;
37                }
38                //取出来合并了之后把桶清光数据
39                bucketList.get(j).clear();
40            }
41        }
42        return arr;
43    }
44}

性质:1、时间复杂度:O(kn)  2、空间复杂度:O(n+k)  3、稳定排序  4、非原地排序

总结

用一张图汇总了10大排序算法的性质

如果你是复习/学习十大排序算法,一定要自己不看示例代码手动实现一遍,一定要自己不看示例代码手动实现一遍,一定要自己不看示例代码手动实现一遍。

转载自十大算法

java 十大经典排序算法的更多相关文章

  1. JAVA十大经典排序算法最强总结(含JAVA代码实现)

    十大经典排序算法最强总结(含JAVA代码实现)   最近几天在研究排序算法,看了很多博客,发现网上有的文章中对排序算法解释的并不是很透彻,而且有很多代码都是错误的,例如有的文章中在“桶排序”算法中对每 ...

  2. JAVA十大经典排序算法最强总结(含JAVA代码实现)

    0.排序算法说明 0.1 排序的定义 对一序列对象根据某个关键字进行排序. 0.2 术语说明 稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面: 不稳定:如果a原本在b的前面,而a=b,排 ...

  3. 一文搞定十大经典排序算法(Java实现)

    本文总结十大经典排序算法及变形,并提供Java实现. 参考文章: 十大经典排序算法总结(Java语言实现) 快速排序算法—左右指针法,挖坑法,前后指针法,递归和非递归 快速排序及优化(三路划分等) 一 ...

  4. 十大经典排序算法最强总结(含JAVA代码实现)(转)

    十大经典排序算法最强总结(含JAVA代码实现)   最近几天在研究排序算法,看了很多博客,发现网上有的文章中对排序算法解释的并不是很透彻,而且有很多代码都是错误的,例如有的文章中在“桶排序”算法中对每 ...

  5. 十大经典排序算法最强总结(含Java、Python码实现)

    引言 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法.排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面 ...

  6. 十大经典排序算法(java实现、配图解,附源码)

    前言: 本文章主要是讲解我个人在学习Java开发环境的排序算法时做的一些准备,以及个人的心得体会,汇集成本篇文章,作为自己对排序算法理解的总结与笔记. 内容主要是关于十大经典排序算法的简介.原理.动静 ...

  7. 十大经典排序算法(Javascript实现)

    前言 总括: 本文结合动图详细讲述了十大经典排序算法用Javascript实现的过程. 原文博客地址:十大经典排序算法 公众号:「菜鸟学前端」,回复「666」,获取一揽子前端技术书籍 人生有情泪沾衣, ...

  8. 十大经典排序算法(python实现)(原创)

    个人最喜欢的排序方法是非比较类的计数排序,简单粗暴.专治花里胡哨!!! 使用场景: 1,空间复杂度 越低越好.n值较大: 堆排序 O(nlog2n) O(1) 2,无空间复杂度要求.n值较大: 桶排序 ...

  9. 十大经典排序算法+sort排序

    本文转自:十大经典排序算法,其中有动图+代码详解,本文简单介绍+个人理解. 排序算法 经典的算法问题,也是面试过程中经常被问到的问题.排序算法简单分类如下: 这些排序算法的时间复杂度等参数如下: 其中 ...

随机推荐

  1. onclick="this.src=this.src+'?'"是什么意思?

    onclick="this.src=this.src+'?'" 这是表示当前图片链接 在当前链接值的基础上添加了一个问号 譬如当前src="check.aspx" ...

  2. The property does not exist in XML namespace

    自定义依赖属性,绑定在xaml文件中,无问题. 但是编译失败,报 The property does not exist in XML namespace 错误. 发现如果依赖属性定义在本程序集中,在 ...

  3. redis 基础 Redis 数据类型

    String(字符串) Hash(哈希) List(列表) Set(集合) zset(sorted set:有序集合)

  4. vs下载为0的问题

    问题描述:win10 下无法安装VS2017,visual studio installer下载进度始终为0,点击取消按钮后,也没有反应,visual studio installer也关闭不掉: 具 ...

  5. 面试问题之——给你图片的url,你能知道它所占的字节空间吗?

    从一个需求说起 这标题起得有点标题党,实际情况是我最近在做一个公司内部工具时,遇到了这么一个需求,给定一个静态资源站点上某张图片的url(比如https://a.xxxcdn.com/demo.jpg ...

  6. 使用SQL语句还原数据库 2012.3.20

    --返回由备份集内包含的数据库和日志文件列表组成的结果集. --主要获得逻辑文件名 USE master RESTORE FILELISTONLY FROM DISK = 'g:\back.Bak' ...

  7. SpringMVC笔记三

    课程安排: 第一天:springmvc的基础知识 什么是springmvc? springmvc框架原理(掌握) 前端控制器.处理器映射器.处理器适配器.视图解析器 springmvc入门程序 目的: ...

  8. Java基础 -3.2

    逻辑运算符 三目(赋值)运算符 合理地利用三目运算可以避免一些大范围的程序编写 三目运算是一种所谓的赋值运算的处理 它是需要设置一个逻辑关系的判断之后才可以进行的赋值操作 基本语法: 关系运算?关系满 ...

  9. LeetCode 19. Remove Nth Node From End of List(删除链表中倒数第N个节点)

    题意:删除链表中倒数第N个节点. 法一:递归.每次统计当前链表长度,如果等于N,则return head -> next,即删除倒数第N个节点:否则的话,问题转化为子问题“对head->n ...

  10. 第1节 Scala基础语法:13、list集合的定义和操作;16、set集合;17、map集合

    list.+:5 , list.::5: 在list集合头部添加单个元素5 : li1.:+(5):在list集合尾部添加单个元素5: li1++li2,li1:::li2:在li1集合尾部添加il2 ...