精华内容
下载资源
问答
  • 二路归并排序算法
    2021-03-01 06:41:11

    package com.sorts; public class MergeSort { /** * 合并有序序列start~middle和middle~end到一个有效序列 * 数组是a[start-1~middle-1]与a[middle~end-1]两个子序列 * 时间复杂度为: * 最好O(nlogn);平均O(nlogn);最坏O(nlogn) * 空间复杂度为: O(n) * @param a * @param start * @param middle * @param end */ public static void merge(int a[], int start, int middle, int end){ int i,j,n1,n2; n1 = middle-start+1; n2 = end-middle; int[] L = new int[n1]; int[] R = new int[n2]; for(i=0;i R[j]){ a[start+i+j-1] = R[j];//注意赋值到start起点基数 j++; }else{ a[start+i+j-1] = L[i];//注意赋值到start起点基数 i++; } } //剩余一个序列的尾 while(j

    更多相关内容
  • 二路归并排序算法

    2022-07-13 17:45:59
    二路归并排序算法简单理解就是两两进行比较,然后把他们合并到一起。 通俗理解就是去买衣服的时候,经常会货比三家,看了一个店选两件衣服,然后又去另外一个店选了同款的两件衣服。看价格排序,或者性价比排序 一下...

    二路归并排序算法简单理解就是两两进行比较,然后把他们合并到一起。 通俗理解就是去买衣服的时候,经常会货比三家,看了一个店选两件衣服,然后又去另外一个店选了同款的两件衣服。看价格排序,或者性价比排序 一下,看哪个更便宜,或者性价比更高。

     

    二路归并排序关键点:

    1. 相邻的两两进行比较,然后把他们合并在一起。相邻的两两最开始是单个元素,合并之后就会翻倍。
    2. 二路归并排序的过程,需要先拆分元素,然后再合并。

    二路归并排序是不稳定的排序,时间复杂度o(n^2), 空间复杂度o(n)

    举一个例子看一下二路归并排序的过程:

    以数组 5,3,2,1 为例子

    1. 先拆分数组, 分成两组,5,3 和 2,1
    2. 继续拆分,两组变成四组, 5,3,2,1各自都是一组
    3. 两两进行合并,合并成两组, 3,5和1,2
    4. 再两两合并,合并成一组, 1,2,3,5

     

    看一下用python是如何实现的

    def merge_list(elements, low, mid, high):
        tmp = [0] * (high - low + 1)
        index = 0
        left = low
        right = mid + 1
        while left <= mid and right <= high:
            if elements[left] < elements[right]:
                tmp[index] = elements[left]
                left = left + 1
            else:
                tmp[index] = elements[right]
                right = right + 1
            index = index + 1
    
        while left <= mid:
            tmp[index] = elements[left]
            left = left + 1
            index = index + 1
    
        while right <= high:
            tmp[index] = elements[right]
            right = right + 1
            index = index + 1
    
        for i in range(len(tmp)):
            elements[low + i] = tmp[i]
    
    
    def merge_sort(elements, low, high):
        if low < high:
            mid = int((low + high) / 2)
            merge_sort(elements, low, mid)
            merge_sort(elements, mid + 1, high)
            merge_list(elements, low, mid, high)
    
    
    if __name__ == '__main__':
        arr = [5, 2, 3, 1]
        merge_sort(arr, 0, len(arr) - 1)
        print(arr)

    复制

    运行后输出结果:

    [1, 2, 3, 5]

    展开全文
  • 设定两个指针,最初位置分别为两个已经排序序列的起始位置2.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置3.重复步骤3直到某一指针达到序列尾4.将另一序列剩下的所有元素直接...

    /***********************************************************************************************

    1.设定两个指针,最初位置分别为两个已经排序序列的起始位置

    2.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

    3.重复步骤3直到某一指针达到序列尾

    4.将另一序列剩下的所有元素直接复制到合并序列尾

    归并排序:

    归并排序具体工作原理如下(假设序列共有n个元素):

    1.将序列每相邻两个数字进行归并操作,形成floor(n / 2)个序列,排序后每个序列包含两个元素

    2.将上述序列再次归并,形成floor(n / 4)个序列,每个序列包含四个元素

    3.重复步骤2,直到所有元素排序完毕

    归并排序是稳定的,它的最差,平均,最好时间都是O(nlogn)。但是它需要额外的存储空间.

    归并排序法(Merge Sort,以下简称MS)是分治法思想运用的一个典范。

    其主要算法操作可以分为以下步骤:

    Step 1:将n个元素分成两个含n/2元素的子序列

    Step 2:用MS将两个子序列递归排序(最后可以将整个原序列分解成n个子序列)

    Step 3:合并两个已排序好的序列

    ************************************************************************************************/

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    using namespace std;

    void Random(int a[],int n)

    {

    int i=0;

    srand( (unsigned)time( NULL ) );

    while(i

    {

    a[i++]=rand();

    }

    }

    void merge(int *a, int low, int mid, int high) //归并操作

    {

    int k, begin1, begin2, end1, end2;

    begin1 = low;

    end1 = mid;

    begin2 = mid + 1;

    end2 = high;

    int *temp = (int *) malloc((high - low + 1) * sizeof(int));

    for(k = 0; begin1 <= end1 && begin2 <= end2; k++) //自小到大排序

    {

    if(a[begin1] <= a[begin2])

    temp[k] = a[begin1++];

    else

    temp[k] = a[begin2++];

    }

    if(begin1 <= end1) //左剩

    memcpy(temp + k, a + begin1, (end1 - begin1 + 1) * sizeof(int));

    else //右剩

    memcpy(temp + k, a + begin2, (end2 - begin2 + 1) * sizeof(int));

    memcpy(a + low, temp, (high - low + 1) * sizeof(int)); //排序后复制到原数组

    free(temp); //释放空间

    }

    void merge_sort(int *a, unsigned int begin, unsigned int end)

    {

    int mid;

    if(begin < end)

    {

    mid=begin+(end-begin)>>1;

    //mid = (end + begin) / 2; 防止数据加法溢出

    merge_sort(a, begin, mid); //分治

    merge_sort(a, mid + 1, end); //分治

    merge(a, begin, mid, end); //合并两个已排序的数列

    }

    }

    int main()

    {

    int a[20];

    Random(a,20);

    for(int i=0;i<20;i++)

    {

    cout<

    }

    merge_sort(a, 0, 20-1);

    for(int i=0;i<20;i++)

    {

    cout<

    }

    return 0;

    }

    展开全文
  • 二路归并模式:每次仅作两个文件的归并;当有多个文件时,采用两两归并的模式,最终得到一个完整的记录文件。 二元归并树:二路归并模式的归并过程可以用一个二元树的形式描述,称之为二元归并树。 贪心求解: 任意...
  • C语言二路归并排序算法, 写了个二路归并的归并排序小代码,直接贴上来
  • 二路归并排序: 时间复杂度:O(nlogn) 外层函数需要遍历的次数与2的指数次有关(外层的时将复杂度为O(logn)),内层函数需要完全遍历所有数据(内层的时间复杂度为O(n)),两个相乘整体的时间复杂度为O(nlogn) 空间...

    基础数据结构之八大排序算法(五)

    ⑤二路归并排序:

    时间复杂度:O(nlogn) 外层函数需要遍历的次数与2的指数次有关(外层的时将复杂度为O(logn)),内层函数需要完全遍历所有数据(内层的时间复杂度为O(n)),两个相乘整体的时间复杂度为O(nlogn)
    空间复杂度:O(nlogn) 额外的辅助变量会影响的问题的规模(内层额外辅助空间brr,外层函数所需额外辅助变量i),整体空间复杂度为O(nlogn)
    稳定性:不稳定 存在跳跃交换

    (以顺序表作为待排序对象)

    1.基本思想
    (1).一开始将所有数据看作单独的个体(队列),这个时候他们都独自有序。
    (2).两个对列两个队列融合(保证融合后有序稳定(不存在跳跃交换))
    (3).重复第二步直到所有数据都到一个队列中。

    以数组arr[]={21,12,7,9,11,98,56,88,66,68}为例:

    在这里插入图片描述
    (这里初始数据一共是10个,第一次1个队列和1个队列融合,第二次2个数据的队列和2个数据的队列融合,第三次4个数据的队列和4个数据的队列融合,第四次8个数据的队列和8个数据(实际上其中只有2个数据)的队列融合),从而看出融合次数的规律:
    在这里插入图片描述
    【设 i 为运行次数,当( i * 2 ) < 总数据个数时继续排序】

    2.具体合并方法

    (1).需要设置一个临时辅助空间 brr 来存放两两队列对比排序完数据。
    (2).左右手对比时,先从左右手中各从左到右对比,两手中较小的那个放到辅助空间 brr 中,循环这样比较直到一只手空了,则剩下的那个手里的数据依次放到辅助空间 brr 中。
    (3).两手放完后,再去抓另外两组

    *设置临时辅助空间 brr 的原因
    例如数组arr[]={7,9,11,12,12,11,88,98,66,68}时:
    在这里插入图片描述
    当只用arr时会导致无序,不稳定,所以需要设立临时辅助空间brr。

    3.代码实现

    <1>.所需头文件和宏替换:

    #include<stdio.h>
    #include<stdlib.h>
    #include<malloc.h>
    #include<stdbool.h>
    
    #define ar arr[]={21,12,7,9,11,98,56,88,66,68}
    #define ELEM_TYPE int
    
    int ar;
    

    <2>.顺序表的建立:

    typedef struct Sqlist
    {
    	ELEM_TYPE* data;
    	int length;
    	int SIZE;
    }Sqlist,*PSqlist;
    

    <3>.顺序表的初始化:

    void Init_Sqlist(PSqlist L)
    {
    	L->data = arr;
    	L->length = 0;
    	L->SIZE = sizeof(arr) / sizeof(arr[0]);
    }
    

    <4>.打印

    void Show(PSqlist L)
    {
    	for (int i = L->length; i < L->SIZE; i++)
    	{
    		printf("%d ", L->data[i]);
    	}
    	printf("\n\n");
    }
    

    <5>.每一次的归并排序:

    void Merge(PSqlist L,int gap)          //控制一次融合,gap是每次融合组中数据的个数
    {
    	ELEM_TYPE* brr = (ELEM_TYPE*)malloc(sizeof(ELEM_TYPE) * L->SIZE);   //申请额外辅助空间brr
    	int i = 0;          //辅助空间的下标
    
    	//左右手的边界
    	int low1 = 0;                           
    	int high1 = low1 + gap - 1;      //有边界=左边界+偏移量
    	int low2 = high1 + 1;
    	int high2 = low2 + gap - 1 < L->SIZE ? low2 + gap - 1 : L->SIZE - 1;
    
    	while (low2 <= high2)              //最外层保证可以抓取值
    	{
    		while (low1 <= high1 && low2 <= high2)        //内层保证两只手都有值可以比较大小
    		{
    			if (arr[low1] <= arr[low2])
    			{
    				brr[i++] = arr[low1++];
    			}
    			else
    			{
    				brr[i++] = arr[low2++];
    			}
    		}
    		//内层循环退出的时候代表有一只手为空,这时直接将不为空的手里的数据依次放到brr中
    
    		while (low1<=high1)         //左手不空时
    		{
    			brr[i++] = arr[low1++];
    		}
    
    		while (low2<=high2)         //右手不空时
    		{
    			brr[i++] = arr[low2++];
    		}
    
    		//已经将这次的左右手都放到brr中了,就让左右手再去抓另外的组
    		low1 = high2 + 1;
    		high1 = low1 + gap - 1;
    		low2 = high1 + 1;
    		high2 = low2 + gap - 1 < L->SIZE ? low2 + gap - 1:L->SIZE - 1;    //这里是决定外层循环退出的关键
    
    	}
    	//外层循环退出代表两种情况:1.此时全部数据都已经排完,目前左右手都是空的,这种情况不用管
    	                          //2.此时左手有值右手没有值,这时只需要将左手的值依次放进brr就可以
    
    	while (low1 < L->SIZE)
    	{
    		brr[i++] = arr[low1++];
    	}
    
    	//此时brr已经满了,只需将brr都覆盖arr即可
    	for (int k = 0; k < L->SIZE; k++)
    	{
    		arr[k] = brr[k];
    	}
    
    	//最后将临时辅助空间释放防止内存泄露
    	free(brr);
    }
    

    <6>.二路归并排序:

    void MergeSort(PSqlist L)          //控制总的融合次数
    {
    	for (int i = L->length + 1; i < L->SIZE; i = i * 2)
    	{
    		Merge(L, i);
    	}
    }
    

    <7>.主函数:

    int main()
    {
    	Sqlist head;
    	Init_Sqlist(&head);
    	printf("初始数据为:");
    	Show(&head);
    
    	MergeSort(&head);
    	printf("二路归并排序后数据为:");
    	Show(&head);
    	return 0;
    }
    

    <8>.运行结果:
    在这里插入图片描述
    希望这篇博客能帮助大家更好的学习和理解二路归并排序
    感谢阅读!

    展开全文
  • 排序算法中的归并排序(Merge Sort)是利用”归并”技术来进行排序。归并是指将若干个已排序的子文件合并成一个有序的文件。 一、实现原理: 1、算法基本思路 设两个有序的子文件(相当于输入堆)放在同一向量中相邻的...
  • C语言二路归并排序算法.rtf
  • 数据结构----二路归并排序

    千次阅读 2021-07-06 21:33:43
    二路归并排序的基本思想 ...一次二路归并排序算法的目标是把若干个长度为k的相邻有序子数组从前、向后进行两两归并,得到个数减半的长度为2k的相邻有序子数组。算法设计中要考虑的一个问题是:若元素个数为2k的整数倍,
  • 排序算法归并排序 上学期的数据结构已经讲过归并排序了,但是上学期太懒了,所以没有动手把代码写出来2333。今天在写算法设计的第章作业,讲的是分治思想。而归并排序的思想就是分治,便乘此机会动手实际...
  • C++实现二路归并排序算法

    千次阅读 2020-11-05 22:21:20
    归并类:二路归并排序 基数类:多关键字排序 九种算法的时间复杂度、空间复杂度和稳定性小结如下: 本文放出二路归并算法的排序算法代码。 二路归并排序 void merge(int R[], int low, int mid, int high) { int ...
  • 本文实例为大家分享了C语言实现归并排序的具体代码,供大家参考,具体内容如下 归并排序的基本思想: 将两个及其以上的有序表合并为一张有序表,把待排序序列通过分治分为若干个有序子序列,然后每两个子序列合并...
  • // 将前后两个相邻有序表归并为一个有序表,设两段有序表A[low..mid]、A[mid+1..high]存放在同一个有序表的相邻位置,先将他们复制到辅助数组B中, // 每次从对应B中的两个段取出一个记录进行关键字的比较,将较小者...
  • 归并排序算法
  • 二路归并排序总结

    2022-07-15 14:21:36
    二路归并排序总结(面试常考)
  • 排序算法之——二路归并排序 二路归并排序的思想: 一次排序过程,将已经各自有序的两个段的数据合并一个段,并且合并后依旧有序 开始,我们认为单个数据是有序的,一个数据就是一个段,一次排序之后,两个数据就是...
  • 二路归并排序(基于分治的思想,先分解再合并)   算法思想:先分解,然后两两归并,直到合成一个新的有序表。   相关代码如下: // 归并排序:先分解再合并 void Merge_sort(int[] array, int left, int ...
  • def merge(a, b): c = [] #定义空列表 h = j = 0 #定义双列表的...]) #调用上面的算法函数 进行合并 return merge(left, right) if __name__ == '__main__': a = [1,2,3,53,21,11,32,55,765,77] print (merge_sort(a))
  • 基于递归调用的二路归并排序的理解与运用
  • 二路归并排序的C++实现 #include<iostream> #include<vector> using namespace std; typedef int elem; void mergeArray(vector<elem>&, int, int, int, int (*)(elem, elem)); void ...
  • 归并排序就是采用分治进行排序:(1)将一个数组分成小的2个数组分别进行排序;(2)之后将分出来的已经拍好序的数组进行合并;import java.util.Scanner;public class MergeSort {int[] a=null;int[] b=null;int n;...
  • 参考引言:在排序算法中快速排序的效率是非常高的,但是还有种排序算法的效率可以与之媲美,那就是归并排序归并排序和快速排序有那么点异曲同工之妙,快速排序:是先把数组粗略的排序成两个子数组,然后递归再粗略...
  • //归并函数 void merge(int *R, int low, int high) { int mid = (low + high) / 2; //需要定义一个额外的数组,临时存放归并的结果 int maxSize = high - low + 1; int temp[maxSize]; int k = 0; int i = ...
  • 二路归并排序C++实现

    千次阅读 2019-07-13 11:20:21
    二路归并排序 基本思想 二路归并排序就是将两个有序子表归并成一个有序表。首先我们得有一个算法用于归并:两个有序表放在同一数组的相邻位置上,arr[left]到arr[center-1]为第一个有序表,arr[center]到arr[right...
  • 本文实例讲述了Python实现的归并排序算法。分享给大家供大家参考,具体如下: 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治(Divide and Conquer)的一个非常典型的应用。 将已有序的子序列...
  • 自底向上的二路归并排序算法(C/C++)
  • 这里写自定义目录标题前言归并算法简介归并算法实现1、二路归并原理2、java代码实现3、测试结果 前言 算法是迷人的,但通常也相当抽象。我在学习的时候,看了很多博客,教程,发现往往他们的代码都不太一样。这对我...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 23,191
精华内容 9,276
关键字:

二路归并排序算法