排序算法(下)

来源:互联网 发布:最好赚钱的软件 编辑:程序博客网 时间:2024/06/05 00:22

归并排序

归并排序是将两个较小的有序数组归并为一个较大的有序数组。将一个数组排序,可以先将该数组分成两半,将这两半分别排序,最后将两个有序的子序列归并。根据这种思想,人们发明了一种简单的递归排序算法,归并排序。
归并排序的步骤可以用下图的一个例子进行说明:
这里写图片描述
首先利用分割的方法将带排序的序列分割成一个个的子序列,直到每个子序列只剩一个元素(有序),再对每个子序列进行合并。具体的实现代码如下:

/*     * 归并排序     */    public static void mergeSort(int[] A){        sort(A,0,A.length - 1);    }    /*     * 排序     */    private static void sort(int[] A,int lo,int hi){        if(hi <= lo)            return;        int mid = lo + (hi - lo) / 2;  //防止溢出        sort(A, lo, mid);   //将左半边排序        sort(A, mid + 1, hi);   //将右半边排序        merge(A,lo,mid,hi); //归并结果    }    /*     * 原地归并     */    private static void merge(int[] a, int lo, int mid, int hi) {        //将两个数组归并        int i = lo,j = mid + 1;        int[] aux = new int[hi + 1];        for (int k = lo; k <= hi; k++) {//将原来的数组复制到辅助数组中            aux[k] = a[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(aux[i] > aux[j])    //右半边元素小于左半边元素,取右半边                a[k] = aux[j++];            else                        //左半边元素小于右半边元素,取左半边                a[k] = aux[i++];        }    }

归并排序的特点如下:
1、归并排序是一种渐进最优的基于比较排序的算法,其时间复杂度为n*lgn;
2、归并排序算法的空间复杂度与元素个数成正比;
3、归并排序算法是稳定的;
4、归并排序算法对输入的初始次序不敏感。

快速排序

快速排序是应用最广泛的的排序算法,采用递归调用对元素进行排序,是基于比较排序算法的一个著名算法。主要思想如下:

算法由以下步骤组成:
1、如果数组中只有一个元素或者没有元素则返回;
2、选择数组中的一个元素作为枢轴点;
3.将数组分为两部分,一部分大于枢轴点,一部分小于枢轴点;
4、对两部分数组递归调用该方法。
这里写图片描述

算法实现代码如下:

public class Quicksort {    public static void quickSort(int[] A){        sort(A,0,A.length - 1);    }    private static void sort(int[] A,int lo,int hi){        if(hi <= lo)    //只有一个元素或者数组为空,则直接返回            return;        int pivot = partition(A,lo,hi);//切分数组        sort(A,lo,pivot - 1);//对左半部分排序        sort(A,pivot+1,hi);//对右半部分排序    }    /*     * 对数组进行切分     */    private static int partition(int[] a, int lo, int hi) {        int left = lo,right = hi+1;        int pivot = a[lo];//选择第一个元素为基准进行切分        while(left < right){            while(a[++left] <= pivot){                if(left == hi)                    break;            }            while(a[--right] >= pivot)                if(right == lo)                    break;            if(left < right)                swap(a,left,right);         }        swap(a,lo,right);        return right;    }    /*     * 交换     */    private static void swap(int[] A,int i, int j) {        int temp = A[i];        A[i] = A[j];        A[j] = temp;    }

测试代码如下:

public static void main(String[] args) {        int[] A = {4,8,5,3,6,3,7,29,10,11};        for (int i = 0; i < A.length; i++) {            System.out.print(A[i] + "   ");        }        System.out.println();        System.out.println("=========================================");        quickSort(A);        for (int i = 0; i < A.length; i++) {            System.out.print(A[i] + "   ");        }    }

快速排序的特点:
1、快速排序在平均情况或者最好情况下,时间复杂度均为O(N*lgN),最坏情况下的时间复杂度为O(n*n)。
2、快速排序实现简单,适用于各种不同的输入数据,在一般应用中比其他算法快得多;
3、快速排序算法非常脆弱,在实现是要非常小心才能避免低劣的性能。

原创粉丝点击