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

引言

小明和小森是超市的货架管理人员,他们每天都要确保货架上的商品摆放整齐、有序。一天,他们发现一个货架上的商品有些混乱,需要尽快进行补货。由于该货架上的商品种类繁多,不同种类的商品之间还要考虑价格、销量等因素,因此给补货工作带来了一些挑战。

小明和小森商量了一下,决定利用归并排序的原理来对货架上的商品进行排序。他们首先将货架上的商品按照一定的规则进行分类,例如按照商品类别、价格或销售量等因素进行分类。然后,他们将每个分类中的商品按照归并排序的算法进行排序,以便更好地管理货架上的商品。

在排序过程中,小明和小森还注意到了一些问题。例如,有些商品的价格较高,但是销量却不太好,需要调整它们的位置;有些商品的摆放角度不够合适,需要调整它们的朝向。这些问题都得到了及时的解决,最终使得货架上的商品更加整齐、有序。

经过小明和小森的努力,超市的货架变得更加整齐、有序,顾客购物也更加方便。小明和小森也因此得到了超市经理的表扬和奖励。他们认识到,利用归并排序等算法可以更好地管理超市的货架和商品,提高工作效率和顾客满意度。

B站在合并视频时,可能会使用一种叫做“推荐算法”的技术。这种算法会考虑用户的观看历史、兴趣爱好、视频主题等因素,然后根据这些信息将相关的视频推荐给用户。

B站的推荐算法可能会通过以下步骤来合并视频:

分析用户的观看历史和兴趣爱好,了解用户喜欢哪些类型的视频。
筛选出与用户兴趣相关的视频,这些视频可能来自用户关注的人、喜欢的品牌、或者是与用户历史观看记录相似的视频。
对筛选出来的视频进行排序,根据视频的发布时间、点击率、点赞数、评论数等因素进行加权计算,得出每个视频的得分。
将得分的视频进行合并,形成一个新的推荐列表。
除了推荐算法之外,B站还可能会使用其他技术来提高合并视频的质量,例如人工智能、深度学习等。这些技术可以通过对大量数据的分析,更精准地预测用户的兴趣爱好和行为,从而提供更个性化的推荐服务。

在这里插入图片描述

总之,B站在合并视频时使用的是一种综合性的技术,其中可能包括归并排序等排序算法来提高推荐列表的质量和个性化程度。

归并排序算法核心思路

在这里插入图片描述
利用分而治之算法分成两个子序列 (左子序列,右子序列)
实现看左子序列
在这里插入图片描述
分而治之算法分到Left==Right 停止 一步步地返回 当然不要忘了还有mid+1 ,到Right 还没有有序 当然 我这没有合并 所以看起来也怪怪的
先把分而治之算法核心弄明白后再来 弄合并算法

在这里插入图片描述
经过mid+1到Right的范围 分治 合并 应该 左子序列 必须有序
在这里把他的执行步骤归纳为一张图

在这里插入图片描述
哈哈,骚脑的二叉搜索树 没错就是我 因为递归真不好弄,所以 我把他们归纳为树形结构 方便思查看
当然现在肯定知道该怎么做了吧,只要v 我 50 就… 开个玩笑 ! 我希望的是 记录这些技术 即使忘记了也能通过 文章来复习复习 因为我只能这样,别无选择!
由于已经知道如何走 如何分治; 那么就没必要画步骤了 把他的执行步骤归纳为一张图 右子序列
在这里插入图片描述
当左右分布均匀的合并后

--------------------------------------------
left ; 0 right :7
--------------------------------------------
 |--------------------- 左边到中间 -----------------------
 left : 0 mid :3 right :7
--------------------------------------------
left ; 0 right :3
--------------------------------------------
 |--------------------- 左边到中间 -----------------------
 left : 0 mid :1 right :3
--------------------------------------------
left ; 0 right :1
--------------------------------------------
 |--------------------- 左边到中间 -----------------------
 left : 0 mid :0 right :1
--------------------------------------------
left ; 0 right :0
--------------------------------------------
 --------------------- 中间+1到右边|-----------------------
 left : 0 mid+1 :1 right :1
--------------------------------------------
left ; 1 right :1
--------------------------------------------
 -------------------- 合并  ------------------------ |
left ; 0 right :1
 left : 0 mid :0 right :1
 --------------------- 中间+1到右边|-----------------------
 left : 0 mid+1 :2 right :3
--------------------------------------------
left ; 2 right :3
--------------------------------------------
 |--------------------- 左边到中间 -----------------------
 left : 2 mid :2 right :3
--------------------------------------------
left ; 2 right :2
--------------------------------------------
 --------------------- 中间+1到右边|-----------------------
 left : 2 mid+1 :3 right :3
--------------------------------------------
left ; 3 right :3
--------------------------------------------
 -------------------- 合并  ------------------------ |
left ; 2 right :3
 left : 2 mid :2 right :3
 -------------------- 合并  ------------------------ |
left ; 0 right :3
 left : 0 mid :1 right :3
 --------------------- 中间+1到右边|-----------------------
 left : 0 mid+1 :4 right :7
--------------------------------------------
left ; 4 right :7
--------------------------------------------
 |--------------------- 左边到中间 -----------------------
 left : 4 mid :5 right :7
--------------------------------------------
left ; 4 right :5
--------------------------------------------
 |--------------------- 左边到中间 -----------------------
 left : 4 mid :4 right :5
--------------------------------------------
left ; 4 right :4
--------------------------------------------
 --------------------- 中间+1到右边|-----------------------
 left : 4 mid+1 :5 right :5
--------------------------------------------
left ; 5 right :5
--------------------------------------------
 -------------------- 合并  ------------------------ |
left ; 4 right :5
 left : 4 mid :4 right :5
 --------------------- 中间+1到右边|-----------------------
 left : 4 mid+1 :6 right :7
--------------------------------------------
left ; 6 right :7
--------------------------------------------
 |--------------------- 左边到中间 -----------------------
 left : 6 mid :6 right :7
--------------------------------------------
left ; 6 right :6
--------------------------------------------
 --------------------- 中间+1到右边|-----------------------
 left : 6 mid+1 :7 right :7
--------------------------------------------
left ; 7 right :7
--------------------------------------------
 -------------------- 合并  ------------------------ |
left ; 6 right :7
 left : 6 mid :6 right :7
 -------------------- 合并  ------------------------ |
left ; 4 right :7
 left : 4 mid :5 right :7
 -------------------- 合并  ------------------------ |
left ; 0 right :7
 left : 0 mid :3 right :7
11 45 50 116 172 181 186 187

合并算法

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

一个整型数组arr,以及三个整数left、mid和right,分别代表数组的左边界、中间点和右边界,还有一个整型指针TempArr,用于存放合并后的结果。
初始化指针: 然后初始化三个索引i、j和k,分别初始化为left、mid和left。i指向左子数组的起始位置,
j指向右子数组的起始位置,k指向合并后数组的起始位置。
合并过程: 使用一个while循环,条件是i < mid && j <= right,表示当左子数组和右子数组都有元素时,进行合并操作。在循环中,比较arr[i]和arr[j]的大小,将较小的元素复制到TempArr[k],然后将相应的指针向前移动一位。
复制剩余元素: 完成合并操作后,将剩余的左子数组元素(如果存在)复制到TempArr[k],然后同样将指针向前移动一位。接着将剩余的右子数组元素(如果存在)复制到TempArr[k],并将指针向前移动一位。
计算大小并复制: 计算合并后数组的大小(即右边界减去左边界加1),然后copy()将TempArr中的元素复制回原数组arr的相应位置。

归并排序算法专区

// 合并算法  
void Merge(int arr[], int left,int mid ,int right, int* mergeRes, bool(*comp)(const int&, const int&)) {  
    // 定义三个索引,分别原始数组、待合并的两个数组和合并结果数组的起始位置  
    int i = left;  
    int j = mid;  
    int k = left;  
  
    // 循环执行合并操作,直到其中一个数组被完全遍历  
    while (i<mid && j<=right){  
        // 如果左侧数组的当前元素小于右侧数组的当前元素  
        if (comp(arr[i],arr[j])){  
            // 将左侧数组的当前元素放入合并结果数组  
            mergeRes[k++] = arr[i++];  
        }else{  
            // 否则,将右侧数组的当前元素放入合并结果数组  
            mergeRes[k++] = arr[j++];  
        }  
    }  
  
    // 如果左侧数组中还有剩余元素,将其全部放入合并结果数组  
    while (i < mid) {  
        mergeRes[k++] = arr[i++];  
    }     
      
    // 如果右侧数组中还有剩余元素,将其全部放入合并结果数组  
    while (j <= right) {  
        mergeRes[k++] = arr[j++];  
    }  
  
    // 计算待排序数组的大小,为下一次合并做准备  
    int size = (right - left) + 1;  
  
    // 将合并结果数组复制回原始数组,覆盖旧的未排序部分  
    auto mergeResEnd = mergeRes + (left + size);  
    copy(mergeRes + left, mergeResEnd, arr + left);  
}  
  
// 分而治之 归并排序  
void MergeSort(int arr[], int left, int right, int* merges, bool(*comp)(const int&, const int&)){  
    // 如果待排序区间不为空,则继续执行归并排序算法  
    if (left < right) {  
        // 计算待排序区间的中点,用于分割区间为两部分进行递归排序  
        int mid = left + (right - left) / 2;  
        // 递归调用MergeSort对左半部分进行排序,传入的归并结果数组为mergesArr,排序完成后将覆盖原数组arr中的相应部分  
        MergeSort(arr, left, mid, merges, comp);  //左半部分递归调用结束,返回结果后,将结果合并到右半部分,最后完成整个区间的排序。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
        MergeSort(arr, mid + 1, right, merges, comp);  //右半部分递归调用结束,返回结果后,将结果合并到左半部分,最后完成整个区间的排序。     
        Merge(arr, left, mid + 1, right, merges, comp);  //将两个有序数组合并成一个有序数组。注意,此处的arr中左半部分和右半部分是两个独立的、有序的子序列。    
    }     
}

// 归并排序函数,使用分治策略对数组进行排序  
void MergeSort(int arr[], int size, bool(*comp)(const int&, const int&)) {  
    // 检查数组的大小是否大于0,以及比较函数是否存在  
    if (size > 0 && comp) {  
        // 创建一个大小为size的整数数组,用于存放归并排序过程中的临时结果  
        int* mergesArr = new int[size];  
          
        // 对数组进行递归排序,将排序结果存放在mergesArr中  
        MergeSort(arr, 0, size - 1, mergesArr, comp);  
          
        // 释放创建的临时数组,避免内存泄漏  
        delete[] mergesArr;  
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小森程序员

若能帮助到你,小费自愿付费

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值