排序与查找

排序算法

排序算法模板

public class Example {
    public static void sort(Comparable[] a){

    }

    public static boolean less(Comparable v, Comparable w){
        //comparable 比较类当v>w时返回1,v==w时返回0,v<w时返回-1;
        return v.compareTo(w)<0;
    }

    public static void exch(Comparable[] a,int i ,int j){
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
	//打印数组
    public static void show(Comparable[] a){
        for (Comparable comparable : a) {
            System.out.print(comparable + " ");
        }
        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;
    }
}

选择排序

时间复杂度为 O ( n 2 ) O(n^2) O(n2)
空间复杂度为 O ( 1 ) O(1) O(1)(原地排序)

public class Slections {

    public void SlectionSort(Comparable[] a){
        int len = a.length;
        for (int i = 0; i < len-1; i++) {
            for (int j = i; j < len; j++) {
                if(less(a[i],a[j])){
                    Comparable temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
    }

    public static boolean less(Comparable v, Comparable w){
        //comparable 比较类当v>w时返回1,v==w时返回0,v<w时返回-1;
        return v.compareTo(w)<0;
    }

    public static void exch(Comparable[] a,int i ,int j){
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    public static void show(Comparable[] a){
        for (Comparable comparable : a) {
            System.out.print(comparable + " ");
        }
        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) {
        Slections slections = new Slections();
        Comparable[] a = {"f","z","c","m","a"};
        slections.SlectionSort(a);
        slections.show(a);
    }
}

output: z m f c a


插入排序

插入排序的时间复杂度是O(n^2)
空间复杂度是O(1)(原地排序)

public class Slections {

    public void SlectionSort(Comparable[] a){
        int len = a.length;
        for (int i = 0; i < len-1; i++) {
            for (int j = i; j < len; j++) {
                if(less(a[i],a[j])){
                    Comparable temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
    }

    public static boolean less(Comparable v, Comparable w){
        //comparable 比较类当v>w时返回1,v==w时返回0,v<w时返回-1;
        return v.compareTo(w)<0;
    }

    public static void exch(Comparable[] a,int i ,int j){
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    public static void show(Comparable[] a){
        for (Comparable comparable : a) {
            System.out.print(comparable + " ");
        }
        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) {
        Slections slections = new Slections();
        Comparable[] a = {"f","z","c","m","a"};
        slections.SlectionSort(a);
        slections.show(a);
    }
}

output: a c f m z


归并排序

这里的代码参考自算法第四版。
归并排序的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

public class Merge {

    
    private Merge() { }

    //代码来自算法第四版,这里aux是辅助空间,这样递归时就无需开辟新的空间
    private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {
        // precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays
        assert isSorted(a, lo, mid);
        assert isSorted(a, mid+1, hi);

        // copy to aux[]
        for (int k = lo; k <= hi; k++) {
            aux[k] = a[k]; 
        }

        // merge back to a[]
        int i = lo, j = mid+1;
        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++];
        }

        // postcondition: a[lo .. hi] is sorted
        assert isSorted(a, lo, hi);
    }

    // mergesort a[lo..hi] using auxiliary array aux[lo..hi]
    private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi) {
        if (hi <= lo) return;
        int mid = lo + (hi - lo) / 2;
        sort(a, aux, lo, mid);
        sort(a, aux, mid + 1, hi);
        merge(a, aux, lo, mid, hi);
    }

   
    public static void sort(Comparable[] a) {
        Comparable[] aux = new Comparable[a.length];
        sort(a, aux, 0, a.length-1);
        assert isSorted(a);
    }


   /***************************************************************************
    *来自模板的粗著函数
    ***************************************************************************/
    public static boolean less(Comparable v, Comparable w){
        //comparable 比较类当v>w时返回1,v==w时返回0,v<w时返回-1;
        return v.compareTo(w)<0;
    }

    public static void exch(Comparable[] a,int i ,int j){
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    public static void show(Comparable[] a){
        for (Comparable comparable : a) {
            System.out.print(comparable + " ");
        }
        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;
    }

    
}

快速排序

快速排序是每次排序选定一个值大的放其左边,小的放其右边的一种算法
快速排序的时间复杂度是 O ( n l o g n ) O(nlogn) O(nlogn),空间复杂度是 O ( 1 ) O(1) O(1).

public class Quick {

    // This class should not be instantiated.
    private Quick() { }

    /**
     * Rearranges the array in ascending order, using the natural order.
     * @param a the array to be sorted
     */
    public static void sort(Comparable[] a) {
        StdRandom.shuffle(a);
        sort(a, 0, a.length - 1);
        assert isSorted(a);
    }

    // quicksort the subarray from a[lo] to a[hi]
    private static void sort(Comparable[] a, int lo, int hi) { 
        if (hi <= lo) return;
        int j = partition(a, lo, hi);
        sort(a, lo, j-1);
        sort(a, j+1, hi);
        assert isSorted(a, lo, hi);
    }

    // partition the subarray a[lo..hi] so that a[lo..j-1] <= a[j] <= a[j+1..hi]
    // and return the index j.
    private static int partition(Comparable[] a, int lo, int hi) {
        int i = lo;
        int j = hi + 1;
        Comparable v = a[lo];
        while (true) { 

            // find item on lo to swap
            while (less(a[++i], v)) {
                if (i == hi) break;
            }

            // find item on hi to swap
            while (less(v, a[--j])) {
                if (j == lo) break;      // redundant since a[lo] acts as sentinel
            }

            // check if pointers cross
            if (i >= j) break;

            exch(a, i, j);
        }

        // put partitioning item v at a[j]
        exch(a, lo, j);

        // now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi]
        return j;
    }

  
    public static Comparable select(Comparable[] a, int k) {
        if (k < 0 || k >= a.length) {
            throw new IllegalArgumentException("index is not between 0 and " + a.length + ": " + k);
        }
        StdRandom.shuffle(a);
        int lo = 0, hi = a.length - 1;
        while (hi > lo) {
            int i = partition(a, lo, hi);
            if      (i > k) hi = i - 1;
            else if (i < k) lo = i + 1;
            else return a[i];
        }
        return a[lo];
    }
    public static boolean less(Comparable v, Comparable w){
        //comparable 比较类当v>w时返回1,v==w时返回0,v<w时返回-1;
        return v.compareTo(w)<0;
    }

    public static void exch(Comparable[] a,int i ,int j){
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    public static void show(Comparable[] a){
        for (Comparable comparable : a) {
            System.out.print(comparable + " ");
        }
        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 class Heap {

    public void HeapSort(Comparable[] a){
        int N = a.length;
        for (int i = N/2; i >=1; i--) {
            sink(a,i);
        }
    }

    //上浮操作
    private void swim(Comparable[] a, int k){
        while (k>1 && k/2<k){
            Comparable temp;
            temp = a[k];
            a[k] = a[k/2];
            a[k/2] = temp;
            k= k/2;
        }
    }

    //下沉操作
    private void sink(Comparable[] a,int k){
        while (2*k < a.length-1){
            int j = 2*k;
            if(j<a.length && a[j].compareTo(a[j+1])<0){
                j++;
            }
            if(! (a[j].compareTo(a[j+1])<0)){
                break;
            }
            Comparable temp = a[k];
            a[k] = a[j];
            a[j] = temp;
            k = j;

        }
    }

    public static void show(Comparable[] a){
        for (Comparable comparable : a) {
            System.out.print(comparable + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Heap heap = new Heap();
        Comparable[] a = {"f","z","c","m","a"};
        heap.HeapSort(a);
        heap.show(a);
    }

}

查找算法

二分查找

二分查找是对有序数组的一种查找方式,每次选取中间的元素与目标元素作比较,然后不断缩小范围的一种排序手段。

public class BinarySerch {

    private boolean Serch(Comparable[] a, Comparable target,int lo,int hi){
        if(a.length == 0 || lo>hi){
            return false;
        }
        int mid = (lo+hi)/2;
        if(a[mid] == target){
            return true;
        }else if(a[mid].compareTo(target) < 0){
            return Serch(a,target,mid+1,hi);
        }else {
            return Serch(a,target,lo,mid-1);
        }
    }

    public boolean Serch(Comparable[] a, Comparable target){
        return Serch( a, target,0,a.length-1);
    }

}

模糊二分查找

查找比目标值大的第一个元素,用到了二分查找查找到最小范围后的第一个数就是其目标值。

public class BinarySercheApplacation {

    public Comparable SerchFirtBiggerNumber(Comparable[] a,Comparable target){
        if(a.length == 0){
            return null;
        }
        if(a[0].compareTo(target)<0){
            return a[0];
        }
        if(a[a.length].compareTo(target)<0){
            return null;
        }
        int n = a.length, left = 0, right = n;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (a[mid].compareTo(target)<=0) left = mid + 1;
            else right = mid;
        }
        return a[right];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值