3-1/3-4归并排序相关

news/2024/5/17 18:26:25 标签: 归并排序

目录

1递归(自顶向下)

1.1版本1:

1.2 版本2:

1.3 版本3:

2.自底向上方法

2.1版本1


1递归(自顶向下)

1.1版本1:

void __merge(int arr[],int left,int mid,int right)
{
    int helper[right-left+1];
    for(int i=left;i<=right;i++)
    {
        helper[i-left]=arr[i];
    }
    int i=left;
    int j=mid+1;
    int k;
    for(k=left;k<=right;k++)
    {
        if(i>mid) //左半部分元素已经处理完毕
        {
            arr[k]=helper[j-left];
            j++;
        }
        else if(j>right) //右半部分已经处理完毕
        {
            arr[k]=helper[i-left];
            i++;
        }
        else if(helper[i-left]<helper[j-left])
        {
            arr[k]=helper[i-left];
            i++;
        }
        else
        {
            arr[k]=helper[j-left];
            j++;
        }

    }
    return;
}

//递归使用归并排序,对arr[l...r]的范围进行排序
void __mergeSort(int arr[],int left,int right)
{
    if(left>=right)
        return;
    int mid=left+(right-left)/2;
    __mergeSort(arr,left,mid);
    __mergeSort(arr,mid+1,right);
    __merge(arr,left,mid,right);
}

void mergeSort(int arr[],int n)
{
    __mergeSort(arr,0,n-1);
}

1.2 版本2:

版本1对近乎有序的数据排序效率较差,因为它不管左右两部分的大小怎么样,都要进行merge,但是实际上,如果arr[mid]已经小于等于arr[mid+1]的话,此时两部分合在一起也是有序的,不用进行merge。

只需要对__mergeSort函数修改如下:

//递归使用归并排序,对arr[l...r]的范围进行排序
void __mergeSort(int arr[],int left,int right)
{
    if(left>=right)
        return;
    int mid=left+(right-left)/2;
    __mergeSort(arr,left,mid);
    __mergeSort(arr,mid+1,right);
    if(arr[mid]>arr[mid+1])  //只有此时才需要进行merge
        __merge(arr,left,mid,right);
}

1.3 版本3:

版本1中,__mergeSort函数递归到只有一个数据的时候才返回,但是实际上,当数据量比较小的时候可以转而使用插入排序进而提高性能。

因为,一方面,当数据量比较小的时候,数组近乎有序的概率比较大,此时插入排序比较有优势;

另一方面,当数据量小到一定程度的时候,插入排序会比归并排序快一些。

只需要对__mergeSort函数修改如下:

//根据前面学过的插入排序进行简单的修改
void insertionSort(int arr[],int left,int right)
{
    
    for(int i=left+1;i<=right;i++)
    {
        int temp=arr[i];
        int j;
        for(j=i;j>left && arr[j-1]>temp;j--)
        {
            arr[j]=arr[j-1];
        }
        arr[j]=temp;
    }
    return;
}


//递归使用归并排序,对arr[l...r]的范围进行排序
void __mergeSort(int arr[],int left,int right)
{
    if(right-left<=15)  //15是一个经验数值,可以根据情况进行修改
    {
        insertionSort(arr,left,right);
        return;
    }
        
    int mid=left+(right-left)/2;
    __mergeSort(arr,left,mid);
    __mergeSort(arr,mid+1,right);
    if(arr[mid]>arr[mid+1])  //只有此时才需要进行merge
        __merge(arr,left,mid,right);
}

2.自底向上方法

2.1版本1

void mergeSortBU(int arr[],int n)
{
    for(int sz=1;sz<=n;sz+=sz)
    {
        for(int i=0;i+sz<n ;i+=2*sz)
        {
            __merge(arr,i,i+sz-1,min(n-1,i+2*sz-1)); //和前面的版本1相同
        }
    }
    return;
}


http://www.niftyadmin.cn/n/1032255.html

相关文章

3-5---3-9快速排序相关

目录 1.快速排序 1.1 版本1&#xff1a; 1.2 版本2&#xff1a; 1.3 版本3&#xff1a; 1.4 版本4&#xff1a; 1.5 版本5&#xff1a; 2 归并排序和快速排序的衍生问题 2.1逆序对问题 2.2 取数组中第n大的元素 1.快速排序 1.1 版本1&#xff1a; 中间过程&#xff…

5/2 二分搜索树

#include <iostream> #include <queue> #include <cassert> using namespace std;template <typename Key,typename Value> class BST{ private:struct Node{ //定义节点Key key;Value value;Node* left;Node* right;Node(Key key,Value value){keyk…

5/9---5/11二分搜索树的局限性及相关问题

1.二分搜索树可能退化为链表 改进&#xff1a;平衡二叉树 平衡二叉树的一种实现&#xff1a;红黑树 平衡二叉树的其他实现&#xff1a;2-3树、AVL树、Splay 树 2.其他相关结构 平衡二叉树和堆的结合&#xff1a;Treap Trie 3.各种各样的树

力扣滑动窗口

https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/yi-ge-mo-ban-miao-sha-10dao-zhong-deng-n-sb0x/

Ansible自动化运维(一)

一、Ansible简介 1.Ansible是什么 ​ Ansible是新出现的自动化运维工具&#xff0c;基于Python开发&#xff0c;集合了众多运维工具&#xff08;puppet、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量系统配置、批量程序部署、批量运行命令等功能。 Ansible是…

HTTP各版本的不同

http是什么&#xff1f; http是计算机世界里专门在两点之间传输文字、图片、音视频等超文本数据的约定和规范。 http1.0 简单&#xff0c;应用广泛 无状态&#xff1a;好处和坏处-------cookie session 明文传输&#xff1a;好处和坏处 不安全 http1.1 长连接&#xff…

Ansible自动化运维二

1.管理Ansible配置文件 Ansible的配置文件 ​ 通过修改 Ansible 的配置文件来自定义 Ansible安装的行为。Ansible的配置文件可以存在于多个位置&#xff0c;根据不同的情况来选择使用不同的配置文件。 ​ 使用/etc/ansible/ansible.cfg ​ /etc/ansible/ansible.cfg是默认的…