java 排序算法总结(冒泡,选择,插入,桶排序,快排)

这篇文章是对一些常见的排序算法的总结,会持续更新。代码写多了就知道,越是基础的东西越重要,只有掌握了这些最基本的排序算法,才能在遇到实际问题的时候,灵活变通,巧妙地解决。每一个排序的总结我都写在代码注释里了,上代码:

【版权申明】转载请注明出处(请尊重原创,博主保留追究权)
http://blog.csdn.net/qq_24295537/article/details/78025375
出自【yangLiHai_的博客】

/**
 * 公共的交换元素方法
 */
public static void swap(int[] arr,int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
}


/**
 * 冒泡排序
 * 冒泡排序是一种最简单的排序算法,说简单是理解起来简单。通过内循环每次比较两个相邻的元素
 * 内循环结束后,拿出一个最值放在末尾,然后通过外循环再次执行,得到第二个最值。外循环要-1,
 * 因为没必要对最后一个元素进行排序。同理,内循环也要-1,同时要-i,因为i后边的几位已经排好序了。
 * @param arr
 */
public static void bubbleSort(int[] arr){
    for (int i = 0; i < arr.length-1; i++) {
        for (int j = 0; j < arr.length-i-1; j++) {
            if (arr[j]>arr[j+1]) {
                swap(arr, j, j+1);
            }
        }
    }
}


/**
 * 选择排序
 * 选择排序和冒泡排序很类似,理解难度都一样。同样是两个for循环,外循环需要-1,道理等同于上边的冒泡排序,
 * 内循环第一次比较的是相邻的两个元素,拿出比较的结果放在左边,然后和相邻的元素的下一个元素比较,比较结果同样放在左边,
 * 循环结束后,最左侧的元素放置的就是这个最值,然后通过外循环再次进入下一轮内循环,结束后得到第二个最值放在左边。
 * 选择排序和冒泡排序的不同是:
 * 1.冒泡排序每次内循环都是比较相邻的两个元素,而选择排序会跨越多个元素比较,
 * 2.选择排序每一次比较的值放在左边,冒泡排序每一次比较的值放在右边,
 * 相同的是他们的效率都一样低(cry)
 * @param arr
 */
public static void selectSort(int[] arr){
    for (int i = 0; i < arr.length-1; i++) {
        for (int j = i+1; j < arr.length; j++) {
            if (arr[i]>arr[j]) {
                swap(arr, i, j);
            }
        }
    }
}

/**
 * 插入排序
 * 插入排序的起始位置并不是第一个,而是第二个,所以i=1,i之前的元素可以被认为是已经排好序的。
 * 每一次for循环遍历都是拿i元素去和第i-1个元素进行比较,如果比i-1还小,那么第i-1个元素向后移动一位到i,
 * 再拿i元素和第i-2个元素比较,同样执行以上操作,重复执行几次之后,直到找到排好序的元素小于等于i元素的位置,
 * 然后把元素赋值给此位置,然后继续执行下一次for循环
 * @param arr
 */
public static void insectionSort(int[] arr){
    for (int i = 1; i < arr.length; i++) {
        if (arr[i-1]>arr[i]) {
            int temp = arr[i];
            int j = i;
            while (j>0 && arr[j-1]>temp) {
                arr[j] = arr[j-1];
                j--;
            }
            arr[j] = temp;
        }
    }
}

/**
     * 快速排序是排序里边效率最高的的一种,只有shell排序能和他媲美。个人认为是比较难理解,
     * 我也是三番五次才完全理解透彻。需要三个参数,除了数组arr以外,还需要传入数组第一个参数的下标,和最有一个下标。
     * 总体思想:先找一个key,作为参照物,然后拿分别拿两端的数据去和key比较,根据比较结果进行交换,一轮交换后key的位置确定下来,
     * 并且key左侧的值都比key小,右侧的值都比key大,然后用同样的方法对key两侧的值进行排序。
     * 第一步:记录在方法内记录下标的副本,就是i和j,同时记录第一个下标的值为key,key就是我们所说的参照物。
     * 第二步:首先拿arr[j]和key比较,如果比key大,则j--,然后拿arr[i]和key比较,如果比key小,则i++。
     * 第三步:两个while循环执行结束之后,arr[j]<key,arr[i]>key,则交换i,j的数据,交换之后,arr[j]>key,arr[i]<key.
     * 第四步:重新执行第二步,直至i=j,这个时候把arr[left](也就是key)和arr[j],交换之后arr[j]左边的数据都比key小,
     * 右边的数据都比key大,执行到这一步,我们的思路基本就清晰了。
     * 第五步:用递归的思维方式,对arr[j]左边的和右边的数据分别排序,递归完成之后,我们就得到一个有序的数组。
     * 注意事项:一定要先从j开始进行while循环,因为j停止的时候找到的是比key小的位置,最终i和j相遇后所在的位置需要和arr[left]交换的,
     * 如果先从i开始while循环,那么最终i和j相遇后所在的位置一定会比arr[left]大,如果和arr[left]交换后就不会得到效果。
     * @param arr
     * @param left
     * @param right
     */
public static void quickSort(int[] arr,int left, int right) {
    if (left>right) return;
    int i = left;
    int j = right;
    int key = arr[i];
    while(i!=j) {
        while(j>i && arr[j]>=key) {
            j--;
        }
        while(j>i && arr[i]<=key) {
            i++;
        }
        if (j>i) {
            swap(arr, i, j);
        }
    }

    arr[left] = arr[j];
    arr[j] = key;

    quickSort(arr, left, i-1);
    quickSort(arr, i+1, right);
}

/**
*桶排序
*/
public static void bucketSort(int[] arr,int maxlength) {
        for (int i = 0; i < maxlength; i++) {
            int[][] tempData = new int[10][arr.length];
            int index[] = new int[10];
            Arrays.fill(index, 0);
            int pider = (int)Math.pow(10, i);
            for (int j = 0; j < arr.length; j++) {
                int temp = arr[j] ;
                int key = temp / pider % 10;
                tempData[key][index[key]] = arr[j];
                index[key]++;
            }

            int conter=0;
            for (int j = 0; j < tempData.length; j++) {
                for (int z  = 0; z < index[j]; z++) {
                    arr[conter] = tempData[j][z];
                    conter++;
                }
            }
        }
        return ;
    }
发布了17 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_24295537/article/details/78025375