风也温柔

计算机科学知识库

java堆排序算法 十大排序算法 JAVA代码

  文章目录

  参考了 这篇博客

  总体总结表:这个有个错误就是归并排序需要一个o(n)的辅助数组

  这里写图片描述

  #冒泡排序

  主要思想:外层循环从1到n-1,内循环从当前外层的元素的下一个位置开始,依次和外层的元素比较,出现逆序就交换。

  特点: sort(稳定性排序)、In-place sort(不占用额外的空间,只是交换元素)

  最优复杂度:当输入数组就是排好序的时候,复杂度为O(n),而快速排序在这种情况下会产生O(n^2)的复杂度。

  最差复杂度:当输入数组为倒序时java堆排序算法,复杂度为O(n^2)

  插入排序比较适合用于“少量元素的数组”。

  其实插入排序的复杂度和逆序对的个数一样,当数组倒序时,逆序对的个数为n(n-1)/2,因此插入排序复杂度为O(n^2)。

   public class BubbleSort {

        public static void main(String[] args) {
            int[] array = new int[]{2, 3, 5, 8, 9, 0, 4, 5, 1, 6, 8, 7};
            sort(array);
            System.out.println(Arrays.toString(array));
            
        }
        private static void sort(int[] array) {
            int n = array.length;
            for(int i = 0; i < arr.length - 1; i++){
                for(int j = 0; j < arr.length - 1 - i; j++){
                    if(arr[j] > arr[j+1]){
                        int temp = arr[j];
                        arr[j] = arr[j+1];
                        arr[j+1] = temp;
                    }
                }
            }
        }
             
    }

  在算法导论思考题2-2中又问了”冒泡排序和插入排序哪个更快“呢?

  插入排序的速度直接是逆序对的个数,而冒泡排序中执行“交换“的次数是逆序对的个数,因此冒泡排序执行的时间至少是逆序对的个数,因此插入排序的执行时间至少比冒泡排序快。

  #插入排序

  主要思想:

  特点: sort(稳定性排序)、In-place sort(不占用额外空间)

  最优复杂度:当输入数组就是排好序的时候,复杂度为O(n),而快速排序在这种情况下会产生O(n^2)的复杂度。

  最差复杂度:当输入数组为倒序时,复杂度为O(n^2)

  插入排序比较适合用于“少量元素的数组”。

  其实插入排序的复杂度和逆序对的个数一样,当数组倒序时,逆序对的个数为n(n-1)/2,因此插入排序复杂度为O(n^2)。

   public class InsertSort {

        public static void main(String[] args) {
            int[] array = new int[]{2, 3, 5, 8, 9, 0, 4, 5, 1, 6, 8, 7};
            sort(array);
            System.out.println(Arrays.toString(array));
        }
        private static void sort(int[] array) {
            int n = array.length;
            for (int i = 1; i < n; i++) {
                for (int j = i ; j >0 ; j--) {
                    if (array[j] < array[j - 1]) {
                        int temp = array[j];
                        array[j] = array[j - 1];
                        array[j-1] = temp;
                    }
                }
            }
        }
    }

  插入排序的改进:内循环发现逆序不交换,采用整体右移,直到没有逆序的时候把元素放在该位置

   public class InsertSort2 {

        public static void main(String[] args) {
            int[] array = new int[]{2, 3, 5, 8, 9, 0, 7, 5, 1, 6, 8, 7};
            sort(array);
            System.out.println(Arrays.toString(array));
        }
        private static void sort(int[] array) {
            int n = array.length;
            for (int i = 1; i < n; i++) {
                int key = array[i];
                int j = i -1;
                while (j >= 0 && array[j]>key) {
                    array[j + 1] = array[j];
                    j--;
                }
                array[j+1] = key;
            }
        }
    }

  问题:快速排序(不使用随机化)是否一定比插入排序快?

  答:不一定,当输入数组已经排好序时java堆排序算法 十大排序算法 JAVA代码,插入排序需要O(n)时间,而快速排序需要O(n^2)时间。

  #选择排序

  特性:In-place sort, sort。

  思想:每次找一个最小值。

  最好情况时间:O(n^2)。

  最坏情况时间:O(n^2)。

   public class SelectSort {

        public static void main(String[] args) {
            int[] array = new int[]{2, 3, 5, 8, 9, 0, 7, 5, 1, 6, 8, 7};
            sort(array);
            System.out.println(Arrays.toString(array));
        }
        private static void sort(int[] array) {
            int n = array.length;
            for (int i = 0; i < n-1; i++) {
                int min = i;
                for (int j = i+1; j < n; j++) {
                    if (array[j] < array[min]) min = j;
                }
                int temp = array[i];
                array[i] = array[min];
                array[min] = temp;
                
            }
        }
    }

  #希尔排序

  思想:基于插入排序,交换不相邻的元素已对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。思想是使数组中任意间隔为h的元素都是有序的,这样的数组称为h有序数组.

  特性:In-place sort, sort。

  思想:每次找一个最小值。

  最好情况时间:O(n)。

  最坏情况时间:O(n^2)。

   public class ShellSort {

        public static void main(String[] args) {
            int[] array = new int[]{2, 3, 5, 8, 9, 0, 7, 5, 1, 6, 8, 7, 15};
            sort(array);
            System.out.println(Arrays.toString(array));
        }
        private static void sort(int[] array) {
            int n = array.length;
            int h = 1;
            while (h= 1) {
                for (int i = h; i < n; i++) {
                    for (int j = i; j >= h && (array[j] < array[j - h]); j -= h) {
                        int temp = array[j];
                        array[j] = array[j - h];
                        array[j-h]= temp;
                    }
                }
                h /=3;
            }
        }
    }

  #归并排序

  特点: sort、Out-place sort

  思想:运用分治法思想解决排序问题。

  最坏情况运行时间:O(nlgn)

  最佳运行时间:O(nlgn)

  程序中merge的精髓(也就是排序):左半边用尽,则取右半边元素;右半边用尽,则取左半边元素;右半边的当前元素小于左半边的当前元素,则取右半边元素;右半边的当前元素大于左半边的当前元素,则取左半边的元素。实际上大部分发生的都是后面两句话,前面两句只是特殊情况而已。

  自顶向下:

  <pre>public class MergeSort {

public static void main(String[] args) {
    int[] array = new int[]{2, 3, 5, 8, 9, 0, 7, 5, 1, 6, 8, 7};
    mergeSort(array);
    System.out.println(Arrays.toString(array));
}
private static void mergeSort(int[] array) {
    int[] aux = new int[array.length];
    sort(array, aux, 0, array.length - 1);
}
private static void sort(int[] array, int[] aux, int lo, int hi) {
    if (hi hi) array[k] = aux[i++];

<p>堆排序算法 删除堆顶元素_java堆排序算法_排序精算法

        else if (aux[j]