排序算法简述

归并排序(Merge sort)是建立在归并操作上的一种有效、稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并

总结:归并是将子序列合并的意思,合并的方法是用辅助列实现。

快速排序:使用递归的思想,设定分界值,其左侧和右侧,将小于分界值的数据放在左侧,大于分界值的数据放在右侧;左右侧又可以设定分界值,无限递归(调用自身)。

递归和分治是两种不同的算法实现方式。递归是调用自身,而分治是将问题拆分成多个无重叠子问题合并子问题的解得到原始问题的解。分治可以使用递归实现,也可以使用其他算法,如深度优先搜索、回溯、自顶向下动态规划。递归可以用来写分治,也可以用来写别的,如DFS、树的遍历。分治可以用递归写,也可以不用递归写,但用队列加循环完成稍微麻烦

外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的

外部排序常采用的排序方法是归并排序        

mapreduce中的排序算法即作用

KEY相同,分划分到一个分区且只能划分到一个分区。 划分方式按KEY的HASHCODE进行计算。

哈希冲突:不同的键可能具有相同的哈希值,从而被分配到同一个分区中。这种情况下,同一分区内的键是不同的。

mapperReducer中的排序

    在这3次排序中第一次是在内从缓冲区做的排序,使用的算法是快速排序,第二次排序和第三次排序都是在文件合并阶段发生的,使用的是归并排序

第一次排序

     当map函数产生输出时,会首先写入内存的环形缓冲区,当达到设定的阈值,在刷写磁盘之前,后台线程会将缓冲区的数据划分成相应的分区。在每个分区中,后台线程按键进行内排序。

一旦缓冲区内容达到阈值(mapreduce.map.io.sort.spill.percent,默认0.80,或者80%),就会会锁定这80%的内存,并在每个分区中对其中的键值对按键进行sort排序,具体是将数据按照partition和key两个关键字进行排序,排序结果为缓冲区内的数据按照partition为单位聚集在一起,同一个partition内的数据按照key有序。

第二次排序

    在Map任务完成之前,磁盘上存在多个已经分好区,并排好序的、大小和缓冲区一样的溢写文件,这时溢写文件将被合并成一个已分区且已排序的输出文件。由于溢写文件已经经过第一次排序,所以合并文件时只需要再做一次排序就可使输出文件整体有序。

当整个map任务完成溢出写后,会对磁盘中这个map任务产生的所有临时文件(spill文件)进行归并(merge)操作生成最终的正式输出文件。此时的归并是将所有spill文件中的相同partition合并到一起,并对各个partition中的数据再进行一次排序(sort),生成key和对应的value-list

第三次排序

     在shuffle阶段,需要将多个Map任务的输出文件合并,由于经过第二次排序,所以合并文件时只需要再做一次排序就可使输出文件整体有序 。

 当属于该reducer的map输出全部拷贝完成,则会在reducer上生成多个文件(如果拖取的所有map数据总量都没有内存缓冲区,则数据就只存在于内存中),这时开始执行合并操作,即磁盘到磁盘merge,Map的输出数据已经是有序的,Merge进行一次合并排序,所谓Reduce端的sort过程就是这个合并的过程,采取的排序方法跟map阶段不同,因为每个map端传过来的数据是排好序的,因此众多排好序的map输出文件在reduce端进行合并时采用的是归并排序,针对键进行归并排序。

你可能感兴趣的:(排序算法,算法)