ywrby

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

排序算法API

返回值 名称(参数) 作用
void sort(Comparable[] a) 对传入的数据数组进行排序
boolean less(Comparable v,Comparable w) 比较两个可比较数据类习惯的数据,返回比较结果布尔值
void exch(Comparable[] a,int i,int j) 交换索引为i和j的数据
void show(Comparable[] a) 打印数组
boolean isSorted(Comparable[] a) 判断是否经过排序

选择排序

选择排序的过程就是不断从数组中找出最小值的过程,首先,遍历整个数组找到最小值,将它与首个元素交换,然后,遍历剩余数组,找到此时最小值,与第二位交换。如此往复,经过N轮,获得排好序的数组

package cn.ywrby.sorts;


import cn.ywrby.tools.StopWatch;

import java.util.Random;

/*
* 选择排序
* 遍历N次,每次遍历第n项以后最小的元素,并与第n项交换
* */

public class SelectionSort {
    public static void sort(Comparable[] a) {
        for(int i=0;i<a.length;i++){
            int min=i;
            for(int j=i+1;j<a.length;j++){
                if(less(a[j],a[min])) {
                    min = j;
                }
            }
            exch(a,i,min);
        }
    }

    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 = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    private static void show(Comparable[] a) {
        System.out.print("After sort : ");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + "  ");
        }
        System.out.println();
    }

    public static boolean isSorted(Comparable[] a) {
        for (int i = 0; i < a.length-1; i++) {
            if (!less(a[i],a[i+1])){return false;}
        }
        return true;
    }
    public static void main(String[] args){
        int N=200;
        Comparable<Double>[] test=new Comparable[N];
        System.out.print("before sort : ");
        for(int i=0;i<N;i++){
            double data=Math.random();
            System.out.print(data+"  ");
            test[i]=data;
        }
        System.out.println();
        StopWatch watch=new StopWatch();
        sort(test);
        double time=watch.elapsedTime();
        System.out.println(time);
        /*
         * assert关键字:assert [boolean 表达式]
         * 如果[boolean表达式]为true,则程序继续执行。
         * 如果为false,则程序抛出AssertionError,并终止执行。
         */
        assert isSorted(test);
        show(test);
    }
}

算法分析:

对于长度为N的数组。选择排序大约需要N^2/2次比较,和N次交换

不难看出,i=0时,比较了N-1次,最坏情况即每一次比较都导致一次交换,共交换N-1次,i=1时,比较了N-2次,最坏情况交换N-2次,以此类推,最坏情况下,需要比较,交换(N-1)+(N-2)+(N-3)+…+2+1=N*(N-1)/2 ~ N^2/2

算法特性:

运行时间和输入无关

数据移动最少


插入排序

逐项从数组中取出项,将该项与前面各项逐个进行比较,直至其大于前一项小于后一项。

package cn.ywrby.sorts;

/*
* 插入排序
* 依序遍历整个数组遍历到某一元素时,不断将其与之前元素比较
* 直到其到达某一位置使其原位置以前所有的元素都有序
* */

import cn.ywrby.tools.StopWatch;

public class InsertionSort {
    public static void sort(Comparable[] a) {
        int N=a.length;
        for(int i=0;i<N-1;i++){  //逐个遍历元素
            for(int j=i+1;j>0&&less(a[j],a[j-1]);j--) {  //不断与之前元素比较并交换
                exch(a,j,j-1);
            }
        }
    }

    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 = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    private static void show(Comparable[] a) {
        System.out.print("After sort : ");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + "  ");
        }
        System.out.println();
    }

    public static boolean isSorted(Comparable[] a) {
        for (int i = 0; i < a.length-1; i++) {
            if (!less(a[i],a[i+1])){return false;}
        }
        return true;
    }
    public static void main(String[] args){
        int N=200;
        Comparable<Double>[] test=new Comparable[N];
        System.out.print("before sort : ");
        for(int i=0;i<N;i++){
            double data=Math.random();
            System.out.print(data+"  ");
            test[i]=data;
        }
        System.out.println();
        StopWatch watch=new StopWatch();
        sort(test);
        double time=watch.elapsedTime();

        /*
         * assert关键字:assert [boolean 表达式]
         * 如果[boolean表达式]为true,则程序继续执行。
         * 如果为false,则程序抛出AssertionError,并终止执行。
         */
        //assert isSorted(test);
        show(test);
        System.out.println("time="+time);
    }
}

算法分析:

最坏情况下,需要N2/2次比较和交换,一般情况下需要N2/4次比较和交换,最好情况下需要N-1次比较和0次交换

最坏情况就是每次比较都要进行交换,并且每一项进行的比较都达到最大值(从当前位置到达数组首端),所以其运行过程中比较和交换次数=(1+2+3+…+(N-1)) ~ N^2/2

算法特性:

插入排序在处理部分有序的数组时是极其高效的

插入排序对于小规模数组也是高效的


希尔排序

插入排序的主要问题在于无法处理大型数组,以及面对非部分有序数组时并不高效,希尔排序有效解决了这个问题

希尔排序首先确定一个h,将以h为间隔的元素设为一组,分别对各组进行插入排序(利用了插入排序对于小数组高效的特性),然后逐渐缩小h,使数组部分有序,当h为1时,也就彻底成为了插入排序(由于此时数组已符合部分有序,所以插入排序依然高效)

package cn.ywrby.sorts;

/* 希尔排序
 *
 *
 */

import cn.ywrby.tools.StopWatch;

import java.util.Random;

public class ShellSort {
    public static void sort(Comparable[] a) {
        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;
        }
    }

    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 = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    private static void show(Comparable[] a) {
        System.out.print("After sort : ");
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + "  ");
        }
        System.out.println();
    }

    public static boolean isSorted(Comparable[] a) {
        for (int i = 0; i < a.length-1; i++) {
            if (!less(a[i],a[i+1])){return false;}
        }
        return true;
    }
    public static void main(String[] args){
        int N=1000;
        Comparable<Double>[] test=new Comparable[N];
        System.out.print("before sort : ");
        for(int i=0;i<N;i++){
            double data=Math.random();
            System.out.print(data+"  ");
            test[i]=data;
        }
        System.out.println();
        StopWatch watch=new StopWatch();
        sort(test);
        double time=watch.elapsedTime();
        /*
         * assert关键字:assert [boolean 表达式]
         * 如果[boolean表达式]为true,则程序继续执行。
         * 如果为false,则程序抛出AssertionError,并终止执行。
         */
        assert isSorted(test);
        show(test);
        System.out.println("time="+time);
    }
}
posted on 2020-04-05 18:35  ywrby  阅读(116)  评论(0编辑  收藏  举报