Java常用排序算法

概述

排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

我们这里说说八大排序就是内部排序。

这里写图片描述

直接插入排序

代码实现

public static void insertSort(int[] a) {
    // 有序序列、无序序列
    // 第一个元素当然是有序的(a[0])
    for (int i = 1; i < a.length; i++) {
        int temp = a[i];
        int j = i - 1;
        for (; j >= 0 && a[j] > temp; j--) {
            // 将大数往后移动一位
            a[j + 1] = a[j];
        }
        a[j + 1] = temp;
    }

}

希尔排序(Shell`s Sort)

希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进。希尔排序又叫缩小增量排序

基本思想:

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

操作方法:

  1. 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
  2. 按增量序列个数k,对序列进行k 趟排序;
  3. 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

代码实现

public static void ShellSort(int[] arr) {
    int gap = arr.length / 2;

    while (1 <= gap) {
        // 把距离为 gap 的元素编为一个组,扫描所有组
        for (int i = gap; i < arr.length; i++) {
            int j = 0;
            int temp = arr[i];

            // 对距离为 gap的元素组进行插入排序
            for (j = i - gap; j >= 0 && temp < arr[j]; j = j - gap) {
                arr[j + gap] = arr[j];
            }
            arr[j + gap] = temp;
        }

        gap = gap / 2; // 减小增量
    }
}

冒泡排序

算法思想

它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,故名。

假设有一个大小为 N 的无序序列。冒泡排序就是要每趟排序过程中通过两两比较,找到第 i 个小(大)的元素,将其往上排。

代码实现

public static void bubbleSort(int[] array) {
    int temp = 0; // 用来交换的临时数

    // length-1趟遍历
    for (int i = 0; i < array.length - 1; i++) {
        // 从后向前依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上
        // 每趟 length-i-1次
        for (int j = array.length - 1; j > i; j--) {
            // 比较相邻的元素,如果前面的数大于后面的数,则交换
            if (array[j - 1] > array[j]) {
                temp = array[j - 1];
                array[j - 1] = array[j];
                array[j] = temp;
            }

        }
    }

}

快速排序

快速排序的基本思想

1、先从数列中取出一个数作为基准数
2、分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边
3、再对左右区间重复第二步,直到各区间只有一个数

概括来说为挖坑填数+分治法

扫描二维码关注公众号,回复: 129066 查看本文章

对挖坑填数进行总结

1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。
2.j–由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。

代码实现

public static void quick_sort(int s[], int l, int r) {
    if (l < r) {
        // Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
        int i = l, j = r, x = s[l];
        while (i < j) {
            while (i < j && s[j] >= x) // 从右向左找第一个小于x的数
                j--;
            if (i < j)
                s[i++] = s[j];

            while (i < j && s[i] < x) // 从左向右找第一个大于等于x的数
                i++;
            if (i < j)
                s[j--] = s[i];
        }
        s[i] = x;
        quick_sort(s, l, i - 1); // 递归调用
        quick_sort(s, i + 1, r);
    }
}

总结

各种排序的稳定性,时间复杂度和空间复杂度总结:
这里写图片描述


参考文档:
1. https://blog.csdn.net/happy_wu/article/details/51841244
2. https://blog.csdn.net/qy1387/article/details/7752973

猜你喜欢

转载自blog.csdn.net/thebigdipperbdx/article/details/79806114