归并排序——java

来源:互联网 发布:矩阵函数的导数和积分 编辑:程序博客网 时间:2024/05/19 11:48

归并排序
时间复杂度:O(n*log2(n))
空间复杂度:O(n)
稳定
核心代码

/** * 归并排序 * @author jin */public class Merge {    /**     * 使用递归的方法对原数组进行分组     * @param array     * @param left     * @param right     */    public static void sort(int[] array,int left,int right){        if(left<right){            int center=(left+right)/2;            sort(array,left,center);            sort(array,center+1,right);            merge(array,left,center,right);        }    }    /**     * 对数组进行合并     * @param array     * @param left     * @param center     * @param right     */    public static void merge(int[] array, int left, int center, int right) {        //创建临时数组        int[] tmpArr=new int[array.length];        //创建临时数组的首索引        int tmpIndex=left;        //保存原数组初始时的首索引        int index=left;        //定义右数组的首索引        int rightIndex=center+1;        while(left<=center&&rightIndex<=right){            //把左和右数组的最小元素放入tmpArr数组中            if(array[left]<=array[rightIndex]){                tmpArr[tmpIndex++]=array[left++];            }else{                tmpArr[tmpIndex++]=array[rightIndex++];            }        }            //把剩下的元素放入tmpArr数组中            while(left<=center){                tmpArr[tmpIndex++]=array[left++];            }            while(rightIndex<=right){                tmpArr[tmpIndex++]=array[rightIndex++];            }            //把临时数组的元素给原数组            while(index<=right){                array[index]=tmpArr[index++];            }    }    public static void main(String[] args) {        int[] a={3,5,7,1,6,4,0,8,2,9};        sort(a, 0, a.length-1);        for(int i=0;i<a.length;i++){            System.out.println(a[i]);        }    }}

归并排序是将数组分为若干子数组,这些子数组是有序的,然后把子数组合并为整体的有序数组。
步骤:
(1)先进行分组,直到每组的长度为1为止,需要用到递归;

void sort(int[] a,int left,int right){    if(left<right){        int mid=(left+right)/2;        sort(a,left,mid);        sort(a,mid+1,right);        merge(a,left,mid,right);    }}

(2)合并子数组,先把小点的元素放入临时数组,再把大点的元素放入临时数组,等到都放入临时数组后,再把临时数组中的数据给原数组,完成排序。

void merge(int[] a,int left,int mid,int right){    int[] tmpArr=new int[a.length];//设置一个临时数组    int tmpIndex=left;//临时数组的首索引    int index=left;//原数组的首索引    int rightIndex=mid+1;//右数组的首索引    while(left<=mid&&rightIndex<=right){//当左数组的索引不大于中间索引,并且右索引不大于末索引时,循环        if(a[left]<a[rightIndex]){//如果左数组的值比右数组的值小的话            tmpArr[tmpIndex++]=a[left++];//把左数组的值放到临时数组中        }else{            tmpArr[tmpIndex++]=a[rightIndex++];//把右数组的值放到临时数组中        }    }    //把小的数放到临时数组中之后,开始放大的数进临时数组    while(left<=mid){        tmpArr[tmpIndex++]=a[left++];    }    while(rightIndex<=right){        tmpArr[tmpIndex++]=a[rightIndex++];    }    //把临时数组中的数放回原数组中去    while(left<=right){        a[index]=tmpArr[index++];    }}
0 0