八大排序---归并排序

来源:互联网 发布:jennifer lopez知乎 编辑:程序博客网 时间:2024/06/08 05:23

八种排序的关系:

这里写图片描述

一、基本思想

归并排序将两个有序表合并·成一个新的有序表, 即把待排序的序列分成若干个子序列,每个序列都是有序的,然后将有序子序列合并成整体有序序列。

二、实例

这里写图片描述

三、实现过程解析

归并排序的核心经过两个分解, 合并,
分解: 由于合并中合并的序列必须为有序序列, 如何选择, 不断的惊醒分解, 分解到成一个元素的序列,那一定是一个有序的序列,这就要借助递归, 将一个源序列拆分成一个个有序的序列
然后就是进行合并。

这里写图片描述

3.1 、合并,将两个有序的序列合并成一个有序的序列

首先来看合并部分, 提供连个子序列, 设定为有序的
数组data[] 中
left … center
center … right
合并就是将者两个子序列进行合并。
创建一个临时数组用于存储这个序列的元素, 长度为两个子序列的长度:

int tmpArr = new int[right-left+1];

定义一个变量用于存储存到临时数组中的索引

int third = left;

定义一个变量作为第二个元素的索引记录

int tmp=left;int mid = center+1;

因为两个子序列都是有序序列, 所以从两个序列中依次拿出元素比较, 小的元素存入临时数组中。

        while(left<=center&&mid<=right){            //从两个数组中取出最小的放入中间数组            if(data[left]<=data[mid]){                tmpArr[third++]=data[left++];            }else{                tmpArr[third++]=data[mid++];            }        }

两个序列比较结束, 是以其中一个序列中元素比较完成, 并不知道另一个序列中元素是否比较完了,所以需要将序列中的剩余元素存入临时数组中

while(mid <=right) {    tmpArr[third++]=data[mid++];}while(left <= center) {    tmpArr[third++]=data[left++];}

比较完成, 要将临时数组中的元素,存入原来的数组中

for(i=0; i<tmpArr.length; i++) {    data[tmp++]=tmpArr[i++];}

3.2分解, 分治思想

在上面的示意图中, 可以看到, 不断将待排序的数组进行拆分,最终拆分一个元素,
定义center ,将序列分成两个子序列,
对两部分子序列各自进行排序,(由于这个排序递归执行) 最终拆分成一个个单独元素, 最后才调用merger() 进行合并。

    /**     *      * @param data     * @param left     * @param right     */    public void sort(int[] data, int left, int right) {        if(left<right){            //找出中间索引            int center=(left+right)/2;            //对左边数组进行递归            sort(data,left,center);            //对右边数组进行递归            sort(data,center+1,right);            //合并            merge(data,left,center,right);        }    }

四、java实现

package com.chb.sort;import java.util.Arrays;public class mergingSort {    int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};    public  mergingSort(){        sort(a,0,a.length-1);        for(int i=0;i<a.length;i++)            System.out.println(a[i]);    }    /**     *      * @param data     * @param left     * @param right     */    public void sort(int[] data, int left, int right) {        if(left<right){            //找出中间索引            int center=(left+right)/2;            //对左边数组进行递归            sort(data,left,center);            //对右边数组进行递归            sort(data,center+1,right);            //合并            merge(data,left,center,right);        }    }    /**     * 将两个序列合并     *      * @param data     * @param left     * @param center     * @param right     */    public void merge(int[] data, int left, int center, int right) {        int [] tmpArr=new int[data.length];        int mid=center+1;        //third记录中间数组的索引        int third=left;        int tmp=left;        while(left<=center&&mid<=right){            //从两个数组中取出最小的放入中间数组            if(data[left]<=data[mid]){                tmpArr[third++]=data[left++];            }else{                tmpArr[third++]=data[mid++];            }        }        //剩余部分依次放入中间数组        while(mid<=right){            tmpArr[third++]=data[mid++];        }        while(left<=center){            tmpArr[third++]=data[left++];        }        //将中间数组中的内容复制回原数组        while(tmp<=right){            data[tmp]=tmpArr[tmp++];        }        System.out.println(Arrays.toString(data));    }}
0 0
原创粉丝点击