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

原创 2016年08月29日 18:07:14
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;
    }
}

Bubble, Insertion, Selection, Quick and Heap Sort

Bubble, Insertion, Selection, Quick and Heap Sort
  • guoxiaojie_415
  • guoxiaojie_415
  • 2015年08月15日 15:56
  • 868

常用排序算法时间复杂度和空间复杂度简析

前段时间将排序算法从新整理了一下,并对工作原理,时间复杂度,空间复杂度进行了一些简单分析。内容主要包括快速排序,堆排序,归并排序等三种常用排序算法。...
  • u012301943
  • u012301943
  • 2014年06月24日 21:08
  • 1101

SHELL里用SELECT语句做INSERT语句.

以前再看SQL cookbook的时候看到过用SELECT语句来拼出INSERT语句.当时只是知道有这方法,实际应用没用过.但是今天确实用上了.还是很多.现在Unix环境中有几个bach文件定时的跑....
  • kimsung
  • kimsung
  • 2010年01月19日 15:41
  • 2139

Oracle SQL:insert into语句总结 与 merge into用法总结

insert into语句总结 vs merge into用法总结:1、insert into 插入数据;2、merge into 有则更新,无则插入;...
  • yihuiworld
  • yihuiworld
  • 2015年03月27日 16:33
  • 19704

【Data Structure】nlogn-SortMethods(Quick/Heap/Shell/Merge)

排序算法有很多,主要有: 一、插入排序(包括ShellSort希尔排序) 二、选择排序(包括HeapSort堆排序) 三、快速(Quick)排序 四、归并(Merge)排序 五、基数排序 等 这里针...
  • Ya_da
  • Ya_da
  • 2015年12月05日 22:09
  • 412

merge into 当using后的select结果为空时,不能执行update和insert

今天突然发现merge into功能不起作用了,在网上找了半天,发现是merge into的一个固有bug。 无效语句如下:merge into T_WORK_DRZJ a using (selec...
  • ywl570717586
  • ywl570717586
  • 2015年11月18日 09:56
  • 2221

MergeSort与QuickSort的详细分析

 MergeSort和QuickSort是两种比较类似的sort方式,他们都是通过Divide and Conquer来实现的。都需要使用recursion的方式进行排序。他们的相同之处在于原理上一致...
  • qt_pixie
  • qt_pixie
  • 2006年11月02日 03:06
  • 8122

SQL Server的Merge —— 一步实现 insert,update,delete

USE tempdb GO IF OBJECT_ID('SourceTable') IS NOT NULL DROP TABLE SourceTable IF OBJECT_ID('TargetTab...
  • yenange
  • yenange
  • 2016年09月29日 16:46
  • 853

【PAT】1089. Insert or Merge (25)

According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and g...
  • realxuejin
  • realxuejin
  • 2015年10月22日 16:13
  • 535

MERGE语句用来合并UPDATE和INSERT语句,一张表的大数据操作,要同时进行增删改,提高性能

该命令使用一条语句从一个或者多个数据源中完成对表的更新和插入数据. ORACLE 9i 中,使用此命令必须同时指定UPDATE 和INSERT 关键词,ORACLE 10g 做了如下改动。 1,in...
  • JesseCary
  • JesseCary
  • 2017年03月06日 20:44
  • 1357
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:排序算法(insert ,shell ,quick ,select , merge ,heap)
举报原因:
原因补充:

(最多只允许输入30个字)