归并排序 merge_sort

简介: 归并排序 merge_sort

题目描述

把一个长度为N的数值数组按从小到大的顺序排序并输出

输入描述:

输入为两行 第一行为一个整型数字N 第二行输入N个整型数字num 代表数组里面的元素(每个元素之间用空格隔开)

输出描述:

输出为一行 即为数组从小到大排序后的结果 每个数字之间用空格隔开(行末没有空格)

自测输入

10

1 8 7 6 4 4 4 789 4 1

实际输出

1 1 4 4 4 4 6 7 8 789

归并排序

归是递归,并是合并

先递归,再排序

如何递归,将数组均分成两半(可能有一边多一个{奇数没法均分成两半})

然后将两块再分成四块 (循环了哈)

merge_sort(l,mid);
merge_sort(mid+1,r);

直到分无可分,即长度为一

if(l >= r) return ;

再合并,我们是先递归,再合并

因从我们一定是从小区间先排序,小区间有序了,再去排序大区间

每一次排序区间长度分别为 [1,mid] [mid+1,r]

两个片段采用双指针法,令 i,j 分别为两个区间的头,k为临时数组的头(我们需要一个临时数组来存一下当前排序后的有序数据的结果)

int i=l,j=mid+1,k=1;

然后判断两个指针指向的数据谁小,小的放到临时数组中

while(i<=mid&&j<=r) {
  if(a[i]<=a[j]) b[k++]=a[i++];
  else b[k++]=a[j++];
}

能比较的都比较完了,有剩余数据的那些,说明他们比另一个数组中的所有数据都大,丢在临时数组末尾就好

while(i<=mid) b[k++]=a[i++];
while(j<=r) b[k++]=a[j++];

该区间排序完毕,但是我们是用临时数组来存储排序后的有序数据,所有我们需要把临时数组的数据,迁移到原数组的[l,r]区间内

for(int i=l,j=1;i<=r;i++,j++) a[i]=b[j];
 


给个板子

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5+10;
int a[N];
int b[N];
void merge_sort(int l,int r) {
  //当只剩一个元素的时候就不再进行递归了  
  if(l >= r) return ; 
  int mid = l+r >>1; 
  //先递归  
  merge_sort(l,mid);
  merge_sort(mid+1,r);
  
  //再合并 
  //将已经排好序的左右两边进行合并 
  //两边从前往后双指针进行判断,小的放到 b数组中  
  int i=l,j=mid+1,k=1;
  while(i<=mid&&j<=r) {
    if(a[i]<=a[j]) b[k++]=a[i++];
    else b[k++]=a[j++];
  }
  while(i<=mid) b[k++]=a[i++];
  while(j<=r) b[k++]=a[j++];
  
  //最后再把 b数组替换到 a数组对应位置  
  for(int i=l,j=1;i<=r;i++,j++) a[i]=b[j];
}
int main() {
  //IOS 关闭流,可写可不写,你写个快读效果差不多(一般不会出现什么问题)
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  
  int n;
  while(cin>>n) {
    for(int i=1;i<=n;i++) cin>>a[i];
    merge_sort(1,n);
    for(int i=1;i<=n;i++) cout<<a[i]<<" ";
    cout<<endl;   
  }
  
  return 0;
} 

目录
相关文章
|
9月前
|
搜索推荐 算法 Java
sort-05-insert sort 插入排序算法详解
这是一个关于排序算法的系列文章总结,包括冒泡排序、快速排序、选择排序、堆排序、插入排序等10种排序算法的详细讲解和Java实现。插入排序是一种简单直观的排序算法,通过构建有序序列并逐个插入新元素来排序。提供的Java代码展示了插入排序的实现过程,并附有测试示例。所有算法已开源在GitHub项目[https://github.com/houbb/sort](https://github.com/houbb/sort)中。
|
9月前
|
搜索推荐 算法 Java
sort-03-SelectSort 选择排序算法详解
这是一个关于排序算法的系列文章摘要,包括了各种排序算法的介绍和Java实现。文章列举了冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序以及大文件外部排序的链接和简要说明。其中,选择排序算法被详细解释,它是通过找到未排序序列中的最小元素并将其放到正确位置来逐步构建有序序列的。Java实现中,选择排序的`doSort`方法通过两层循环实现,时间复杂度为`O(N^2)`,是稳定的排序算法。整个排序项目已开源在GitHub。
|
9月前
|
搜索推荐 算法 Java
sort-01-bubble sort 冒泡排序算法详解
这是一个关于排序算法的系列文章摘要。作者整理了10种不同的排序算法,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序和大文件外部排序。文章详细介绍了冒泡排序的工作原理、流程,并提供了代码实现,强调了在实现中考虑的改进点,如统一接口、实用性增强和日志输出。此外,还提供了一个排序接口和工具类以方便使用,并通过测试代码和日志展示了排序过程。整个系列旨在帮助读者理解和掌握排序算法。相关代码已开源在GitHub。
|
9月前
|
搜索推荐 算法 Java
sort-07-merge sort 归并排序
这是一个关于排序算法的系列文章摘要。文章涵盖了多种排序算法的详细解释,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序以及大文件外部排序。归并排序是一种效率为O(nlogn)的排序算法,基于分治法,将序列分成两半,分别排序后再合并。文章提供了Java实现的递归和迭代版本。在归并排序的递归实现中,代码通过不断拆分和合并子序列完成排序,而迭代实现则是通过逐步增大子序列长度并进行两两归并来排序。整个系列可在GitHub找到相关源码。
|
9月前
|
搜索推荐 C++ 索引
常闲排序算法-merge讲解
常闲排序算法-merge讲解
31 1
|
9月前
|
搜索推荐 C++ 索引
常闲排序算法merge讲解
常闲排序算法merge讲解
72 0
2-路插入排序(Two-Way Insertion Sort)
算法介绍 算法描述 算法分析 代码实现 参考
|
搜索推荐 算法 数据可视化
【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)
【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)
139 0
|
存储 搜索推荐
十大排序之Merge Sort 归并排序
十大排序之Merge Sort 归并排序
LeetCode 21. 合并两个有序链表 Merge Two Sorted Lists
LeetCode 21. 合并两个有序链表 Merge Two Sorted Lists