排序算法(Java)

来源:互联网 发布:日期倒计时软件 编辑:程序博客网 时间:2024/06/06 09:32

冒泡排序

    public int[] bubble(int[] ary) {        for (int i = 0; i < ary.length; i++) {            // 每次确保ary[i]是最小的            for (int j = i + 1; j < ary.length; j++) {                if (ary[i] > ary[j]) {                    int temp = ary[j];                    ary[j] = ary[i];                    ary[i] = temp;                }            }        }        return ary;    }

插入排序

    public static int[] insert(int[] ary) {        for (int i = 1; i < ary.length; i++) {            // key就是一个临界点(哨兵),前面是已经排好序的,后面是未排序的            int key = ary[i], j;            // 用key和他前面的值依次比较,发现比该值大就让其后移一位            for (j = i - 1; j >= 0 && ary[j] > key; j--) {                ary[j + 1] = ary[j];            }            // 走到这里说明key>ary[j],因为之前j是已经-1啦,所以在此+1            ary[j + 1] = key;        }        return ary;    }

快速排序

这里写图片描述

package common.algorithm.sort;import java.util.Arrays;/** * 该方法的基本思想是:<br/> * 1.先从数列中取出一个数作为基准数。<br/> * 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。<br/> * 3.再对左右区间重复第二步,直到各区间只有一个数。<br/> * 复杂度O(N*logN) * @author vv * @since 2017/9/4. */public class QuickSort {    /**     * 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小     * 然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。     * @param ary     */    public int[] sort(int[] ary) {        quickSort(ary, 0, ary.length - 1);        return ary;    }    private void quickSort(int[] ary, int low, int high) {        if (low < high) {            // 将ary数组进行一分为二            int middle = partition(ary, low, high);            // 对低字表进行递归排序            quickSort(ary, low, middle - 1);            // 对高字表进行递归排序            quickSort(ary, middle + 1, high);        }    }    /**     * 以list的第一个为中轴pivot = ary[low];比pivot小的放在左边,比其大的放在右边,最后返回pivot     *      * @param ary     * @param low ary的最低位     * @param high ary的最高位     * @return     */    private int partition(int[] ary, int low, int high) {        // 数组的第一个作为中轴,低位的值给了pivot,所以ary[low]空出来了        int pivot = ary[low];        while (low < high) {            // 高位比中轴大,则高位索引-1            while (low < high && ary[high] >= pivot) {                high--;            }            // 高位的值比中轴小,则放到ary[low]上,此后ary[high]又空出来了            ary[low] = ary[high];            // 低位比中轴小,则低位索引+1            while (low < high && ary[low] <= pivot) {                low++;            }            // 比中轴大的记录移到高端            ary[high] = ary[low];        }        // 此处low==high        ary[low] = pivot;        // 返回中轴的位置        return low;    }    public static void main(String[] args) {        QuickSort sorter = new QuickSort();        System.out.println(Arrays.toString(sorter.sort(new int[] { 2, 5, 2, 1, 7, 3 })));    }}

归并排序

package common.algorithm.sort;import java.util.Arrays;/** * 归并排序是分治法(Divide and Conquer)的一个非常典型的应用<br/> * 将已有序的子序列合并,得到完全有序的序列<br/> * 两个有序序列段分别为 R[low, mid] 和 R[mid+1, high]<br/> * 每次从两个段中取出第一个(最小的)比较,将较小者放入temp中。最后将各段中余下的部分直接复制到temp中。 * * <pre> *     {5, 4, 3, 2, 2, 4, 1} *     {4,5} {2,3}  {2,2} {4,1} *     {2,3,4,5} {1,2,2,4} *     {1,2,2,2,3,4,4,5} * </pre> *  * @author vv * @since 2016/9/20. */public class MergeSort {    /**     * 对数组的begin到end 进行排序     *     * @param array 需要排序的数组     * @param begin 起始位置     * @param end 终止位置     */    public void sort(int[] array, int begin, int end) {        // 分到最后,i==j说明该组中只有一个元素了        if (begin < end) {            int middle = (begin + end) / 2;            // 递归处理相关的合并事项            sort(array, begin, middle);// 对第一组排序            sort(array, middle + 1, end);// 对第二组排序            merge(array, begin, middle, end);// 合并两组        }    }    /**     * 对这两组进行合并,从每组中选择最小值进行对比,小的放到temp中     *     * @param array 需要排序的原始数组     * @param low low--middle 为第一组     * @param middle 分界点     * @param high middle+1--high 为第二组     */    private void merge(int[] array, int low, int middle, int high) {        int i = low; // i是第一段序列的下标        int j = middle + 1; // j是第二段序列的下标        int k = 0; // k是临时存放合并序列的下标        int[] temp = new int[high - low + 1]; // array2是临时合并序列        while (i <= middle && j <= high) {            // 判断第一段和第二段取出的数哪个更小,将其存入合并序列temp,并继续向下扫描            if (array[i] <= array[j]) {                temp[k] = array[i];                i++;            } else {                temp[k] = array[j];                j++;            }            k++;        }        // 若第一段序列还没扫描完,将其全部复制到合并序列        while (i <= middle) {            temp[k] = array[i];            i++;            k++;        }        // 若第二段序列还没扫描完,将其全部复制到合并序列        while (j <= high) {            temp[k] = array[j];            j++;            k++;        }        // 将合并序列复制到原始序列中        for (k = 0, i = low; i <= high; i++, k++) {            array[i] = temp[k];        }    }    public static void main(String[] args) {        int[] ary = { 5, 4, 3, 2, 2, 4, 1 };        MergeSort sort = new MergeSort();        sort.sort(ary, 0, ary.length - 1);        System.out.println(Arrays.toString(ary));    }}

堆排序

package common.algorithm.sort;import java.util.Arrays;/** * 归并排序是分治法(Divide and Conquer)的一个非常典型的应用<br/> * 将已有序的子序列合并,得到完全有序的序列<br/> * 两个有序序列段分别为 R[low, mid] 和 R[mid+1, high]<br/> * 每次从两个段中取出第一个(最小的)比较,将较小者放入temp中。最后将各段中余下的部分直接复制到temp中。 * * <pre> *     {5, 4, 3, 2, 2, 4, 1} *     {4,5} {2,3}  {2,2} {4,1} *     {2,3,4,5} {1,2,2,4} *     {1,2,2,2,3,4,4,5} * </pre> *  * @author vv * @since 2016/9/20. */public class MergeSort {    /**     * 对数组的begin到end 进行排序     *     * @param array 需要排序的数组     * @param begin 起始位置     * @param end 终止位置     */    public void sort(int[] array, int begin, int end) {        // 分到最后,i==j说明该组中只有一个元素了        if (begin < end) {            int middle = (begin + end) / 2;            // 递归处理相关的合并事项            sort(array, begin, middle);// 对第一组排序            sort(array, middle + 1, end);// 对第二组排序            merge(array, begin, middle, end);// 合并两组        }    }    /**     * 对这两组进行合并,从每组中选择最小值进行对比,小的放到temp中     *     * @param array 需要排序的原始数组     * @param low low--middle 为第一组     * @param middle 分界点     * @param high middle+1--high 为第二组     */    private void merge(int[] array, int low, int middle, int high) {        int i = low; // i是第一段序列的下标        int j = middle + 1; // j是第二段序列的下标        int k = 0; // k是临时存放合并序列的下标        int[] temp = new int[high - low + 1]; // array2是临时合并序列        while (i <= middle && j <= high) {            // 判断第一段和第二段取出的数哪个更小,将其存入合并序列temp,并继续向下扫描            if (array[i] <= array[j]) {                temp[k] = array[i];                i++;            } else {                temp[k] = array[j];                j++;            }            k++;        }        // 若第一段序列还没扫描完,将其全部复制到合并序列        while (i <= middle) {            temp[k] = array[i];            i++;            k++;        }        // 若第二段序列还没扫描完,将其全部复制到合并序列        while (j <= high) {            temp[k] = array[j];            j++;            k++;        }        // 将合并序列复制到原始序列中        for (k = 0, i = low; i <= high; i++, k++) {            array[i] = temp[k];        }    }    public static void main(String[] args) {        int[] ary = { 5, 4, 3, 2, 2, 4, 1 };        MergeSort sort = new MergeSort();        sort.sort(ary, 0, ary.length - 1);        System.out.println(Arrays.toString(ary));    }}