排序算法——归并算法

参考文章:http://blog.csdn.net/u010275850/article/details/45536535

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide
and Conquer)的一个非常典型的应用,时间复杂度最坏情形为O(NlogN)。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序,称为二路归并。(引自百度百科)

这个算法的基本操作是合并两个已排序的表。基本的合并算法是取两个输入数组A和B,一个输出数组C,以及三个计数器Aptr,Bptr,Cptr.他们初始位置置于对应数组的开始端。A[Aptr]和B[Bptr]中的较小者被拷贝到C中的下一个位置,相关的计数器向前推进一步。当两个输入表有一个用完时,则将另一个表中剩余的部分拷贝到C中。合并例程工作的例子可见下图:

至此,整个合并过程结束。

对于整个序列,归并排序所采用的方法是递归的拆分,然后再递归的合并。可用下图表示:

其代码实现:

#include<stdio.h>
#include<stdlib.h>

void MSort(int *data,int *tmp,int left,int right);
void Mergesort(int *data,int n);
void Merge(int *data,int *tmp,int frist,int mid,int last);

int main()
{
    int i=0;
    int data[8]={24,13,26,1,2,27,38,15};

    printf("Before Sort:\n");
    for(i=0;i<8;i++)
        printf("%d\t",data[i]);
    Mergesort(data,8);

    printf("\nAfter Sort:\n");
    for(i=0;i<8;i++)
        printf("%d\t",data[i]);
    return 0;
}

void MSort(int *data,int *tmp,int left,int right)
{
    int center;
    if(left<right)
    {
        center=(left+right)/2;
        MSort(data,tmp,left,center);//左边有序
        MSort(data,tmp,center+1,right);//右边有序
        Merge(data,tmp,left,center,right);//再将俩个有序数列合并
    }
}

void Mergesort(int *data,int n)
{
    int *tmp;
    tmp=malloc(n*sizeof(int));
    if(tmp!=NULL)
    {
        MSort(data,tmp,0,n-1);
        free(tmp);
    }
    else
        printf("No space for tmp array!!\n");
}

//将两个有序数列a[first...mid]和a[mid+1,...last]合并。
void Merge(int *data,int *tmp,int first,int mid,int last)
{
    int i=first, j=mid+1;
    int n=mid, m=last;
    int k=0;

    while((i<=n)&&(j<=m))
    {
        if(data[i]<=data[j]) //取出较小值放到前面
            tmp[k++]=data[i++];
        else
            tmp[k++]=data[j++];
    }

    while(i<=n)
        tmp[k++]=data[i++];

    while(j<=m)
        tmp[k++]=data[j++];

    for(i=0;i<k;i++)
        data[first + i]=tmp[i];
}
时间: 2024-10-29 00:42:31

排序算法——归并算法的相关文章

排序算法 归并算法(递归+非递归)

部分理论和图来自:http://www.cnblogs.com/jingmoxukong/p/4308823.html  (侵删) 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为二路归并. 归并排序的基本思想 将待排序序列R[0...n-1]看成是n个长度为1的有序序列,将相邻的有序表成对归并,

排序算法 - 归并算法

在实际应用当中,对于数据较大的输入,归并排序是比较快的一个算法.该算法采用的是分治法的思想. 原理:将数据分开排序,然后进行合并,最后形成一个排好的序列. 将其合并输出,如下图所示: 代码实现如下: /** * 归并排序 * * @author Deters * @date 2019/10/12 */ public class MergeSort { /** * 归并 */ private static void merge(Integer[] array, int start, int end

排序算法之归并算法

/* 本例拟在实现排序算法的归并算法,归并算法遵循分治法的思想 归并算法: 归并算法主要用来合并两个已经排好序的序列.用Merge(A,p,q,r)来实现合并, 其中A代表数组,A[p,q]和A[q+1,r]A的两个子数组,且两个数组都已经排好序,归并算法 就是将这两个子数组合并成一个排好序的数组并替代当前的数组A[p,r]. */ public class Merge { public static void main(String[] args) { int[] a = {1,2,3,4,5

算法导论第二章C++实现归并算法排序

归并算法排序的思想算法导论中讲的还算比较清楚. #include<iostream> using namespace std; void guibing(int *_array,int p,int q,int r); void merge_sort(int *_array,int p,int r); int main() { int a[8]={2,4,5,7,1,2,3,6}; int j1=0; int j2=7; merge_sort(a,j1,j2); int i=0; for(;i&

算法:归并算法的递归与非递归形式

归并算法是将两个或两个以上的有序表组合成一个新的有序表,它的原理是:假设初始序列含有n个记录,则可以看成是n个有序子序列,两两归并,得到[n/2]个有序子序列,再次归并--不断重复直至归并到长度为n的有序序列,这样的排序方法称为2路归并排序. 实例一:递归形式的2路归并算法 #define MAXSIZE 4 int data[MAXSIZE] = {2,1,0,3}; /* * 功能:将from数组min到max-1下标数据排好序,最后的结果是to[min]...to[max-1] * 输入:

由归并算法引申出来的其他问题

前言: 上一节刚讲过归并算法是排序算法中比较少见的一种时间复杂度为:θ(nlgn)的算法.而归并算法之所以快的原因在于它用了分治的思想,现实生活中有很多需要用到分治思想解决的问题,下面就举两个例子. 问题一: 给定一个整数数组和任意整数,找到数组中是否有两数的和等于给定的整数. 这个问题如果采用穷举法,则大致思路是这样:首先数组的第一个元素与数组剩下的元素相加,看是否有对应的结果.然后再数组第二个元素与除第一个元素和第二个元素本身之外的元素相加... 后面的操作一次类推.很容易得到时间复杂度为:

归并算法的非递归实现

任何的递归算法都可以转换为非递归算法,而且一般来说递归算法的效率比非递归算法的效率低.但是为啥会有递归算法呢,是因为递归算法看起来思路清晰,而且代码简洁.接下来我主要介绍下归并算法的非递归实现. 主要思想:对于归并算法的非递归实现,我们可以沿着递归实现的逆向方向去思考,递归的思想是自顶向下,将待排序序列不断分解,然后再归并.而非递归的思想就是自底向上,先两两归并,然后再4个4个一起归并,再8个.....在这个过程中一定要注意尾部数据的处理,因为序列的长度不一定就是归并长度的整数倍. 代码实现:

归并算法

归并算法:实现排序. 归:递归.并:合并. 如何递归,如何合并? 使用归并算法的优点:算法的时间复杂度和空间复杂度低. import java.util.Arrays; /** * 归并排序程序,要求输入10个整数,输出排序结果 * Created by ZL on 2016/8/19. */ public class Fourth { public static void main(String[] args) { int[] arr = {9,8,7,6,5,4,3,2,1,0}; sort

POJ2299 求逆序对总数 归并算法解决

逆序对 比如 3 2 1   3之前的数没有比它大的(或者说前面没有数了),所以没有逆序对 2之前的数有3比它大 所以有逆序对+1 1之前的数有 3 2 比它大 所以有逆序对+2 所以 3 2 1 序列 的 总的逆序对为3对 ----- 在归并算法中 合并两个已经排序好的序列时 是从两个序列的首个位置开始进行比较 合并方法传入的参数为:first mid(分界下标) last 第一个序列下标:first ~ mid 第二个序列下标:mid + 1 ~ last 1.如果a[i] <= a[j]