排序算法(insert ,shell ,quick ,select , merge ,heap)

来源:互联网 发布:linux apache ssl下载 编辑:程序博客网 时间:2024/05/16 07:43
public class Sort {    public static void main(String[] args) {        Integer[] a1 = {52, 39, 67, 95, 70, 8, 25, 52};        //String类型已经实现Comparable接口,compareTo方法定义为按字典顺序比较        //(当第一个字符相同时,从第二个比较,以此类推)        String[] a = {"Sa", "Sb", "O", "R", "T", "E", "X", "A", "M", "P", "L", "E"};        System.out.println("排序前:");        for (int i = 0; i < a.length; i++)            System.out.print(a[i] + " ");        //insert(a);        //shell(a);        //quick(a,0,a.length-1);        //select(a);        //merge(a);        heap(a);        System.out.println("\n排序后:");        for (int i = 0; i < a.length; i++)            System.out.print(a[i] + " ");    }    //直接插入算法,时间复杂度为O(n^2),稳定    public static void insert(Comparable[] a) {        for (int i = 0; i < a.length; i++)            for (int j = i; j > 0; j--)                //保证插入排序是稳定算法                if (less(a[j], a[j - 1]))                    exch(a, j, j - 1);                else                    break;  //当后比前大或相等时终止内部的后续for循环,因为j之前的元素已经有序    }    //Shell排序,时间复杂度为O(n^3/2),不稳定    public static void shell(Comparable[] a) {        //选择增量为3x+1        int N = a.length;        int h = 1;        while (h < N / 3)            h = 3 * h + 1;        while (h >= 1) {            for (int i = h; i < N; i++) {                for (int j = i; j >= h && less(a[j], a[j - h]); j -= h)                    exch(a, j, j - h);            }            h = h / 3;        }    }    //快速排序,时间复杂度O(log2n),不稳定    public static void quick(Comparable[] a, int lo, int hi) {        if (hi <= lo)            return;        int j = partition(a, lo, hi);        quick(a, lo, j - 1);        quick(a, j + 1, hi);    }    //快速排序的partition算法,返回中间位置的索引    private static int partition(Comparable[] a, int lo, int hi) {        int i = lo;        int j = hi + 1;        Comparable v = a[lo];        while (true) {            //即使不满足less()的条件,也会先执行++i或者--j            while (less(a[++i], v))                if (i == hi)                    break;            while (less(v, a[--j]))                if (j == lo)                    break;            if (i >= j) break;            exch(a, i, j);        }        exch(a, lo, j);        return j;    }    //直接选择排序,时间复杂度O(n^2),不稳定    public static void select(Comparable[] a) {        int N = a.length;        Comparable temp = null;        for (int i = 0; i < N - 1; i++) {            int min = i;            for (int j = i + 1; j < N; j++)                if (!less(a[min], a[j]))                    min = j;            if (min != i)                exch(a, i, min);        }    }    //2路归并算法,时间复杂度O(nlog2n),稳定    public static void merge(Comparable[] a) {        int N = a.length;        Comparable[] aux = new Comparable[N];        /*for (int k = 0; k <N; k++)             aux[k] = a[k];        不能在此处对aux赋值,因为在for循环中会使得每次传入的值        都为merge(Comparable[]a)中的aux数组。            */        for(int sz=1;sz<N;sz=sz+sz)            for(int lo = 0;lo<N-sz;lo+=sz+sz)                merge(a,aux,lo,lo+sz-1,Math.min(lo+sz+sz-1,N-1));    }    private static void merge(Comparable[]a,Comparable[]aux, int lo, int mid, int hi) {        for (int k = lo; k <= hi; k++) {            aux[k] = a[k];        }        //归并回a数组*/        int i = lo, j = mid + 1;        System.out.println("\nlo: "+lo+" hi: "+hi);        for (int k = 0; k <aux.length; k++)             System.out.print(aux[k]+" ") ;        for (int k = lo; k <= hi; k++) {            if      (i > mid)              a[k] = aux[j++];     //当左半部分指针右移超过中间,只剩右半部            else if (j > hi)               a[k] = aux[i++];     //同上,对边界条件进行判断            else if (less(aux[j], aux[i])) a[k] = aux[j++];                 else                           a[k] = aux[i++];     //i=mid等情况        }        aux =a;        System.out.println("aux2:");        for (int k = 0; k <aux.length; k++)             System.out.print(aux[k]+" ") ;    }    //堆排序,时间复杂度O(nlog2n),不稳定    public static void heap(Comparable[] pq) {        int N = pq.length;        for (int k = N / 2; k >= 1; k--)            sink(pq, k, N);        while (N > 1) {            heapexch(pq, 1, N);            sink(pq, 1, --N);        }    }    private static void sink(Comparable[] pq, int k, int N) {        while (2 * k <= N) {            int j = 2 * k;            if (j < N && heapless(pq, j, j + 1)) j++; //若左节点比右节点小,则移到右节点            if (!heapless(pq, k, j)) break; //若父节点不小于子节点则退出循环            heapexch(pq, k, j); //交换父节点和子节点            k = j;        }    }    private static boolean heapless(Comparable[] pq, int i, int j) {        return pq[i - 1].compareTo(pq[j - 1]) < 0;    }    private static void heapexch(Object[] pq, int i, int j) {        Object swap = pq[i - 1];        pq[i - 1] = pq[j - 1];        pq[j - 1] = swap;    }    private static boolean less(Comparable v, Comparable w) {        return v.compareTo(w) < 0;    }    private static void exch(Comparable[] a, int i, int j) {        Comparable temp = null;        temp = a[i];        a[i] = a[j];        a[j] = temp;    }}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 货车拉的货丢了怎么办 壹米滴答丢货怎么办 物流东西弄丢了怎么办 理赔款账号打错了怎么办 顺丰快递搞丢了怎么办 论文表格跨页了怎么办 网线突然没网了怎么办 室内门高门洞矮怎么办 路基填方土质含水率大怎么办 公路工程材料价格不予调差怎么办 桩基偏位60公分怎么办 定义的跨板受力筋长度不够怎么办 支座梁体预埋钢板忘记埋了怎么办 做nt小孩头朝下怎么办 简历上传的照片太大怎么办 本科毕业论文没写英文摘要怎么办 气泵储气罐有个小眼漏气怎么办 吸拉开关坏了怎么办 窗口数量已达上限怎么办 村土地原始台账没有怎么办 涂防晒霜后出汗怎么办 张拉千斤顶泄荷回油不到位怎么办 隧道二衬打到一半没混凝土怎么办 在左车道骑电动车撞到车怎么办 电镐钻头卡住了怎么办 玩具机器人无线遥控不了怎么办 电锤锤头卸不下来怎么办 打地基没打出硬土层怎么办 中标的项目经理没有B证怎么办 12306证件被注册过怎么办 政府3p项目不给钱怎么办 电气没考上国网怎么办 小区宽带业务被个人承包怎么办 高铁用户名忘了怎么办 昆山社保号是8位怎么办 高铁票误了时间怎么办 动车票没赶上车怎么办 铁路用户名已存在要怎么办 铁路12306用户名忘了怎么办 铁路12306的用户名忘了怎么办 铁路12306注册名已存在怎么办