冒泡快排选择插入希尔排序

  • Post author:
  • Post category:其他


1.选择排序

每次把未排序的数组中的最小值放到当前位置。循环一定次数就达到了排序效果

    public static void main(String[] args) {
        int[] nums = {9, 5, 2, 7, 1};
        for (int i = 0; i < nums.length - 1; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] > nums[j]) {
                    int temp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = temp;
                }
            }
            for (int n : nums
            ) {
                System.out.print(n + " ");
            }
            System.out.println();
        }
    }

一共五个数,找四次最小值即可排序:

第一次:1 9 5 7 2

第二次:1 2 9 7 5

第三次:1 2 5 9 7

第四次:1 2 5 7 9

  • 时间复杂度:O(N2)
  • 空间复杂度:O(1)
  • 不稳定

2.冒泡排序

每次两两比较,如果大小位置不对,就交换,每趟会把最大的数交换到顶端,就像大的泡泡向上浮一样,故名其“冒泡”

    public static void main(String[] args) {
        int[] nums = {9, 5, 2, 7, 1};
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums.length - i - 1; j++) {
                if (nums[j] > nums[j + 1]){
                    int temp = nums[j];
                    nums[j] = nums[j+1];
                    nums[j+1] = temp;
                }
            }
            for (int n : nums
            ) {
                System.out.print(n + " ");
            }
            System.out.println();
        }

    }

一组数: 9 5 2 7 1

我们看一下 9 上浮的过程:

5 9 2 7 1

5 2 9 7 1

5 2 7 9 1

5 2 7 1 9

就这样 9 到有序的位置了,然后在排序剩下的四个数即可,即内层循环的次数可以减 1 了;

关于冒泡的优化:为了明显地观察优化效果,我们数组变为 9 5 2 7 1 10

我们可以看一下,外层循环一共循环六次,分别如下:

第一次:5 2 7 1 9 10

第二次:2 5 1 7 9 10

第三次:2 1 5 7 9 10

第四次:1 2 5 7 9 10

第五次:1 2 5 7 9 10

第六次:1 2 5 7 9 10

我们可以看到,当到第四次的时候就已经有序了,完全不用进行第五次第六次循环,此时跳出循环即达到优化效果

我们可以添加一个判断条件,如果这次循环没有进行数据的交换(说明已经达到有序状态),跳出循环

    public static void main(String[] args) {
        int[] nums = {9, 5, 2, 7, 1, 10};
        boolean f = false;
        for (int i = 0; i < nums.length; i++) {
            f = true;
            for (int j = 0; j < nums.length - i - 1; j++) {
                if (nums[j] > nums[j + 1]) {
                    f = false;
                    int temp = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = temp;
                }
            }
            if (f){
                break;
            }
            for (int n : nums
            ) {
                System.out.print(n + " ");
            }
            System.out.println();
        }

    }

标志 f 用来判断跳出条件

  • 时间复杂度:O(N2)
  • 空间复杂度:O(1)
  • 稳定

3.快速排序

快排的思想是用分割点把数组分成两个部分,分割点左边是比它小的数,右边是比它大的数,然后递归排序左边和右边的数,最终达到有序的目的。

    public static void main(String[] args) {
        int[] nums = {6, 2, 1, 5, 1, 1, 5, 6, 7, 8, 6, 4};
        qsort(nums, 0, nums.length - 1);
        for (int num : nums
        ) {
            System.out.print(num + " ");
        }
    }

    private static void qsort(int[] nums, int left, int right) {
        if (left < right) {
            int base = division(nums, left, right);

            qsort(nums,left,base-1);
            qsort(nums,base+1,right);
        }

    }

    private static int division(int[] nums, int left, int right) {
        int base = nums[left];
        while (left < right) {
            while (true) {
                if (left > right) {
                    break;
                }
                if (nums[right] < base) {
                    nums[left] = nums[right];
                    break;
                } else {
                    right--;
                }
            }
            while (true) {
                if (left >= right) {
                    break;
                }
                if (nums[left] >= base) {
                    nums[right] = nums[left];
                    break;
                } else {
                    left++;
                }
            }
        }
        nums[left] = base;
        return left;
    }
  • 时间复杂度:O(Nlog2N)
  • 空间复杂度:O(Nlog2N)
  • 不稳定

4.插入排序

public class 插入 {
    public static void main(String[] args) {
        int[] nums = {9, 5, 2, 7, 1};
        insertsqrt(nums);

    }

    private static void insertsqrt(int[] nums) {

        for (int i = 1; i < nums.length; i++) {
            int j = 0;
            int temp = nums[i];

            for (j = i - 1; j >= 0 && temp < nums[j]; j--) {
                nums[j + 1] = nums[j];
            }
            nums[j + 1] = temp;
            for (int n : nums
            ) {
                System.out.print(n + " ");
            }
            System.out.println();
        }
    }

}

一组数: 9 5 2 7 1

第一趟: 5 9 2 7 1

第二趟:2 5 9 7 1

第三趟:2 5 7 9 1

第四趟:1 2 5 7 9

  • 时间复杂度:O(N2)
  • 空间复杂度:O(1)
  • 稳定

5.希尔排序

希尔排序就是    步长分组 + 插入排序

把步长分成多组,每组分别进行插入排序。

public class 希尔 {
    public static void main(String[] args) {
        int[] nums = {9,5,2,7,1};
        shellsort(nums);

    }

    private static void shellsort(int[] nums) {
        int N = nums.length / 2;
        while (N != 0) {
            for (int i = 1; i < nums.length; i++) {
                int j = 0;
                int temp = nums[i];

                for (j = i - N; j >= 0 && temp < nums[j]; j -= N) {
                    nums[j + N] = nums[j];
                }
                nums[j + N] = temp;
            }
            for (int num : nums
            ) {
                System.out.print(num + " ");
            }
            System.out.println();
            N /= 2;
        }
    }
}

一组数: 9 5 2 7 1

把步长N分成 length / 2 , 每次步长减半,最终到步长为1即为有序

length = 5

第一趟步长 N = 5/2=2;所以9  2  1 先排序,之后是 5 7排序

1 5 2 7 9

第二趟步长 N = N / 2 = 1;

1 2 5 7 9

此趟步长为1,完成就是有序的了

剩下还有堆排序、基数排序、桶排序、归并排序等等。



版权声明:本文为sinat_41905822原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。