服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - c++ 深入理解归并排序的用法

c++ 深入理解归并排序的用法

2022-11-01 15:27YR_T C/C++

归并排序是典型分治思想的代表——首先把原问题分解为两个或多个子问题,然后求解子问题的解,最后使用子问题的解来构造出原问题的解

hello

昨天发了个堆排序,竟然上了热榜

所以,今天来发一下归并排序

上次的堆排序似乎好多人没看懂,其实这些还是比较基础滴

废话不多说,直接进入正题

分治算法

如果你要学归并排序,首先你要学一下分治

所谓分治,就是分开治理,把大问题化成小问题,逐个解决,再合到一起

这也就是归并排序的精髓

这种算法时间复杂度低,原理也比较简单

归并排序

首先来看这张图

c++ 深入理解归并排序的用法

图片中把一个数组分成了一个一个的元素,在合并的过程中排序

怎么分

分的方法其实很简单,一个递归就可以解决

如果你是初学者,可能没有完全把递归学透彻

简单说,递归就是在函数内部调用自己的函数

递归都要有一个出口,否则就会变成死循环

递归的出口

我们在函数参数上写1)一个数组(要被排序的数组)2)分的开始和结束(first和end)

如果first<end,那么我们可以继续递归,如果不满足条件,递归结束

还要定义一个中间,前面那行代码是分左边,也就是开始~中间,后面那行代码是分右边,也就是中间+1~末尾

?
1
2
3
4
5
6
7
8
void merge_sort(int array[],int first,int end) 
{
    if(first < end){
        int center = (first + end)/2;     //得到中间数
        merge_sort(array,first,center);  
        merge_sort(array,center+1,end);
    }
}

“并”的实现

按照上面的图片,我们每排一下序就给它并一下

具体代码实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void merge(int array[],int first,int center,int end)
{
 
    int n1 = center - first + 1;
    int n2 = end - center;
    int L[n1+1];
    int R[n2+1];
    for(int i = 0; i < n1; i++ )
    {
        L[i] = array[first+i];     //得到前面一部分数组
    }
    //printArray(L,n1);
    for(int j = 0; j < n2; j++ )
    {
        R[j] = array[center+j+1]; //得到后面一部分数组
    }
    //printArray(R,n2);
    L[n1] = 1000;    //设置哨兵
    R[n2] = 1000;    //设置哨兵
    //cout << "R[5] =" << R[4] << endl;
    int k1 = 0;
    int k2 = 0;
    for (int k = first; k <= end; ++k)    //把得到的两个数组进行排序合并
    {  
        //cout << L[k1] <<endl;
        //cout << R[k2] <<endl;
        if(L[k1] <= R[k2])
        {  
            //cout << L[k1] <<endl;
            array[k] = L[k1];
            //cout << array[k] << endl;
            //cout << "k1 =" << k1 << endl;
            k1 = k1 + 1;
        }else{
            //cout << R[k2] <<endl;
            array[k] = R[k2];
            //cout << array[k] << endl;
            //cout << "k2 =" << k2 << endl;
            k2 = k2 + 1;
        }
        //cout << array[k] <<endl;
    }
    //printArray(array,10);
}

加到“分”函数里

因为我们分完了要并,所以我们把“并”函数写进“分”函数里

?
1
2
3
4
5
6
7
8
9
void merge_sort(int array[],int first,int end) 
{
    if(first < end){
        int center = (first + end)/2;     //得到中间数
        merge_sort(array,first,center);  
        merge_sort(array,center+1,end);
        merge(array,first,center,end);
    }
}

完整代码

加上int main()就行

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
using namespace std;
 
/*
* 打印数组
*/
void printArray(int array[],int length)
{
    for (int i = 0; i < length; ++i)
    {
        cout << array[i] << endl;
    }
}
 
/*
* 一个数组从中间分成两个有序数组
* 把这两个有序数组合并成一个有序数组
*/
void merge(int array[],int first,int center,int end)
{
 
    int n1 = center - first + 1;
    int n2 = end - center;
    int L[n1+1];
    int R[n2+1];
    for(int i = 0; i < n1; i++ )
    {
        L[i] = array[first+i];     //得到前面一部分数组
    }
    //printArray(L,n1);
    for(int j = 0; j < n2; j++ )
    {
        R[j] = array[center+j+1]; //得到后面一部分数组
    }
    //printArray(R,n2);
    L[n1] = 1000;    //设置哨兵
    R[n2] = 1000;    //设置哨兵
    //cout << "R[5] =" << R[4] << endl;
    int k1 = 0;
    int k2 = 0;
    for (int k = first; k <= end; ++k)    //把得到的两个数组进行排序合并
    {  
        //cout << L[k1] <<endl;
        //cout << R[k2] <<endl;
        if(L[k1] <= R[k2])
        {  
            //cout << L[k1] <<endl;
            array[k] = L[k1];
            //cout << array[k] << endl;
            //cout << "k1 =" << k1 << endl;
            k1 = k1 + 1;
        }else{
            //cout << R[k2] <<endl;
            array[k] = R[k2];
            //cout << array[k] << endl;
            //cout << "k2 =" << k2 << endl;
            k2 = k2 + 1;
        }
        //cout << array[k] <<endl;
    }
    //printArray(array,10);
}
 
/*
* 分治算法
* 把一个数组从中间分成分开
* 然后进行排序
*/
void merge_sort(int array[],int first,int end) 
{
    if(first < end){
        int center = (first + end)/2;     //得到中间数
        merge_sort(array,first,center);  
        merge_sort(array,center+1,end);
        merge(array,first,center,end);
    }
}
 
int main(int argc, char const *argv[])
{
    int array[10] = {0,6,1,2,3,7,8,9,4,5};
    //merge(array,0,4,9);
    merge_sort(array,0,9);
    printArray(array,10);
    //int center = (0 + 9)/2;
    //cout << "center" << center << endl;
    //cout << "hello";
    return 0;
}

到此这篇关于c++ 深入理解归并排序的用法的文章就介绍到这了,更多相关c++ 归并排序内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/m0_64036070/article/details/123802517

延伸 · 阅读

精彩推荐
  • C/C++C语言中的getchar()使用详解

    C语言中的getchar()使用详解

    大家好,本篇文章主要讲的是C语言中的getchar()使用详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下...

    lin飞子8842022-08-27
  • C/C++一起来了解一下C++的结构体 struct

    一起来了解一下C++的结构体 struct

    这篇文章主要为大家详细介绍了C++的结构体struct,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带...

    南城同学10432022-09-24
  • C/C++C语言中获取和改变目录的相关函数总结

    C语言中获取和改变目录的相关函数总结

    这篇文章主要介绍了C语言中获取和改变目录的相关函数总结,包括getcwd()函数和chdir()函数以及chroot()函数的使用方法,需要的朋友可以参考下...

    C语言教程网12342021-03-10
  • C/C++C语言实现线索二叉树的前中后创建和遍历详解

    C语言实现线索二叉树的前中后创建和遍历详解

    这篇文章主要为大家详细介绍了C语言实现线索二叉树的前中后创建和遍历,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参...

    犀牛超人10892022-09-27
  • C/C++基于Matlab实现水波倒影特效的制作

    基于Matlab实现水波倒影特效的制作

    这篇文章主要介绍了如何利用Matlab制作出水波倒影的特效,文中的示例代码讲解详细,对我们学习Matlab有一定帮助,需要的可以参考一下...

    slandarer9582022-10-31
  • C/C++C++实现图书管理系统课程设计(面向对象)

    C++实现图书管理系统课程设计(面向对象)

    这篇文章主要为大家详细介绍了C++实现图书管理系统课程设计,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    蓉蓉兔68646842022-10-19
  • C/C++C++判断子序列题目详解

    C++判断子序列题目详解

    这篇文章主要为大家介绍了C++判断子序列题目,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助...

    Listen attentively6762022-03-02
  • C/C++C语言函数指针的老生常谈

    C语言函数指针的老生常谈

    这篇文章主要为大家介绍了C语言函数指针,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助...

    青锋杨5732022-03-02