数据结构与算法-归并排序

130 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

归并排序

归并排序顾名思义是利用归并思想实现的排序算法,也叫分治策略。该算法将数组拆分成多个数组然后递归求解。

原理

【3,1,6,7,4,8,2,9,5,0】

初始化数组进行二分直到每个组只有一个数据为止(N个只有一个数据序列)。然后将N个序列不断执行合并操作得到一个有序数组。归并排序核心算法是相邻序列今夕合并操作:将两个有序序列合并成一个有序序列。例如【1,3,4,6,7】,【0,2,5,8,9】两个有序序列合并是【0,1,2,3,4,5,6,7,8,9】。合并的过程不断比较两个数组中的头部数据,小的数先取知道两个数组取完位置。

1.首先对数组做拆分操作分为两个数组。

image.png

2.接着进行拆分数组分为四个数组。

image.png

3.知道拆分数组到每个数组中只有一个数为止

image.png

4.拆分结束后就是合并操作,将相邻两个数据分别进行合并操作。如下所示直到数组合并到只有两个数组为止。

image.png

5.最后两个数组在进行最后的合并操作得到最终有序数组。

image.png

算法代码

//两个有序数组合并方法
void mergeSortDatas(int datas[],int left,int mid,int right){
    int temp[right - left + 1]; // 合并存放的数组
    int i = left; // 左边数组头部下标
    int j = mid + 1; //右边数组头部下标
    int k = 0; //合并数组起始下标
    while(i <= mid && j <= right){  //循环过程
        if(datas[i] < datas[j]){  // 数组数值比较
            temp[k++] = datas[i++];
        }else{
            temp[k++] = datas[j++];
        }
    }
    //存在两个数组长度不一致的情况 比较循环后再对剩余数据做插入操作
    while(i <= mid)
        temp[k++] = datas[i++];
    while(j <= right)
        temp[k++] = datas[j++]; 
    for(int i=0;i<k;i++) // 合并后的数组赋值回到原数组中
        datas[left+i] = temp[i];
}
void mergeSortDatas(int datas[],int left,int right){
    if(left == right) return;
    int mid = (left+ right) / 2;
    mergeSortDatas(datas,left,mid); // 前半段分
    mergeSortDatas(datas,mid+1,right); // 后半段
    mergeSortDatas(datas,left,mid,right); // 归并处理
}
void main(){
    int[] datas;
    int lenght = datas.length();
    mergeSortDatas(datas,0,lenght);
}

归并排序算法推导出的大O记法是N(NlogNN*logN)

总结

归并排序是稳定且高效的排序算法,利用完全二叉树特效排序形式。归并排序每次合并的时间复杂度是O(N),完全二叉树的深度是logNlogN。因此平均情况下归并排序算法就是N(NlogNN*logN)。而且归并排序在最好最坏情况下都为N(NlogNN*logN)