基础算法之归并排序

归并排序也是一种常用的排序算法, 其时间复杂度为O(n*logn), 它的基础是分治的思想。

其基本思路就是把数组分成两组A,B, 如果这两组内的数据都是有序的, 那么就可以很方便的对这两组数据进行合并排序。

但是如何让这两组数据有序呢? 归并法的思想就是把A,B两组各自再分成两组, 依次类推, 当分出来的小组数据只有一个的时候, 即可以认为小组数据已经达到了有序。

然和合并相邻的两个小组就OK了~

归并法的C语言实现如下:

 1 //合并数组的前半部分和后半部分, 前提就是前后两个子数组分别都已经排好序了
 2 void mergeArray(int a[], int first, int mid, int last) {
 3
 4     int i, j, m, n;
 5     i = first, m = mid;
 6     j = mid+1, n = last;
 7     int k = 0;
 8     int temp[SIZE];
 9
10     while(i<=m && j<=n) {
11         if(a[i] < a[j]) {
12             temp[k++] = a[i++];
13         } else {
14             temp[k++] = a[j++];
15         }
16     }
17
18     while(i<=m) temp[k++] = a[i++];
19     while(j<=n) temp[k++] = a[j++];
20
21     for(i=0; i<k; i++) {
22         a[first+i] = temp[i];
23     }
24
25 }
26 //归并排序
27 void merge_sort(int a[], int start, int end) {
28     int mid = (start+end)/2;
29     if(start<end) {
30         merge_sort(a, start, mid);
31         merge_sort(a, mid+1, end);
32         mergeArray(a, start, mid, end);
33     }
34 }

一个简单的测试用例,代码如下:

#include<stdio.h>

#define SIZE 10

//合并数组的前半部分和后半部分, 前提就是前后两个子数组分别都已经排好序了
void mergeArray(int a[], int first, int mid, int last) {

    int i, j, m, n;
    i = first, m = mid;
    j = mid+1, n = last;
    int k = 0;
    int temp[SIZE];

    while(i<=m && j<=n) {
        if(a[i] < a[j]) {
            temp[k++] = a[i++];
        } else {
            temp[k++] = a[j++];
        }
    }

    while(i<=m) temp[k++] = a[i++];
    while(j<=n) temp[k++] = a[j++];

    for(i=0; i<k; i++) {
        a[first+i] = temp[i];
    }

}
//归并排序
void merge_sort(int a[], int start, int end) {
    int mid = (start+end)/2;
    if(start<end) {
        merge_sort(a, start, mid);
        merge_sort(a, mid+1, end);
        mergeArray(a, start, mid, end);
    }
}

int main() {
    int a[SIZE];
    int i;
    printf("Please input the num:\n");
    for(i=0; i<SIZE; i++)
    {
        scanf("%d",&a[i]);
    }
    printf("before the sort:\n");
    for(i=0; i<SIZE; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");

    merge_sort(a, 0, SIZE-1);

    printf("after the sort:\n");
    for(i=0; i<SIZE; i++)
    {
        printf("%d ", a[i]);
    }
    printf("\n");
}

时间: 2024-12-23 00:49:37

基础算法之归并排序的相关文章

十大基础实用算法之归并排序和二分查找

归并排序 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 算法步骤: 1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置 3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 4. 重复步骤3直到某一指针达到序列尾 5. 将另一序列剩下的所有元素直接复制到合并序列尾 用分治策略解决问题分为三步:分解

算法-4.归并排序(自顶向下)

1.基本思想 将两个有序的数组归并成一个更大的有序数组,很快人们就根据这个操作发明了一种简单的递归排序算法:归并排序.要将一个数组排序,可以先(递归地)将它分成两半分别排序,然后将结果归并起来.你将会看到,归并排序最吸引人的性质是它能够保证将任意长度为N的数组排序所需时间和NlogN成正比:它的主要缺点则是它所需的额外空间和N成正比.简单的归并排序如下图所示: 原地归并的抽象方法: 实现归并的一种直截了当的办法是将两个不同的有序数组归并到第三个数组中,实现的方法很简单,创建一个适当大小的数组然后

基础算法之排序--快速排序

1 /************************************************************************************** 2 * Function : 快速排序 3 * Create Date : 2014/04/21 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性. 7 * 任何单位和个人不经本人允许不

算法:归并排序

算法:归并排序 写在前面 归并排序算法是基于一个简单的归并操作:合并两个有序数组来形成一个更大的有序数组. 提炼归并的思想,归并排序就是将一个无序数组先划分成两个部分(递归地),对其分别排序,然后再进行合并. 归并排序无论输入情况,时间复杂度为N*LogN,主要的缺点是使用了一个额外的大小为N的空间. 简单的归并操作: 首先我们思考一下,如何将两个有序数组合并成一个有序数组? 我们应该想到新建一个的新数组re,然后分别从两个数组的左边开始,依次比较两个数组中的元素,将数较小的元素先排入新数组中.

九章算法 基础算法 强化算法 系统设计 大数据 安卓 leetcode 高清视频

leetcode 直播视频讲座录像 九章算法视频录像,PPT 算法班,算法强化班,Java入门与基础算法班,big data项目实战班,Andriod项目实战班 九章算法下载 九章算法面试 九章算法leetcode 九章算法答案 九章算法mitbbs 九章算法班 九章算法ppt 九章算法录像 九章算法培训 九章算法微博 leetcode 视频 九章算法偷录 算法培训 算法班课程大纲: 1 从strStr谈面试技巧与Coding Style(免费试听) 2 二分搜索与旋转排序数组 Binary S

算法录 之 基础算法

这一篇文章主要说说一些基础算法,这些算是很多其他算法的基石. 主要包括  模拟,暴力,枚举,递归,贪心,分治. 1,模拟: 顾名思义,模拟就是...饿,模拟,有一些题目就是给你一些步骤,然后你写代码一步步去模拟那些步骤就行.这类题目主要属于基础题,但是当然如果需要模拟的步骤足够恶心的话,还是比较麻烦的... 具体模拟的例子在之后的练习中会遇到的,按照题目要求一步步做就行,一般算法难度比较小. 2,暴力: 顾名思义,暴力就是...饿,暴力.比如说题目让从平面上的10个点中取三个点,让他们形成的三角

经典白话算法之归并排序

void Merge(int A[],int p,int q,int r){ int i,j,k; //计算子数组A[p..q]的元素个数 int n1 = q - p + 1; //计算子数组A[q+1..r]元素个数 int n2 = r - q; //创建子数组L,R int* L = (int*)malloc(sizeof(int)*(n1+1)); int* R = (int*)malloc(sizeof(int)*(n2+1)); //将子数组A[p..q]赋值到L数组 for(i

算法题——归并排序的原地实现

普通的归并排序,需要一个额外的数组来保存每次merge的结果:如果要求不使用额外空间,那么每次merge的时候需要做一些处理. 思路: 合并left[] 和 right[]时,假如right[0]应该放入left[3],那么:①可以用一个var来保存right[0],然后将left[3]之后的元素右移一次,再将var值放入left[3]:②也可以交换right[0]和left[3]的值,然后left[0]在新的位置向后遍历,找到合适的位置,再把前面的移位.    寻找合适位置的过程是一次插入排序

排序算法系列——归并排序

记录学习点滴,菜鸟成长记 归并排序的英文叫做Merge-Sort,要想明白归并排序算法,还要从“递归”的概念谈起. 1.递归 一般来讲,人在做决策行事的时候是往往是从已知出发,比如,我又要举个不恰当的例子了→_→: 看到漂亮姑娘→喜欢人家→追→女朋友→老婆 但是人家施瓦辛格不是这么想的,人家从小就立志当总统: 要当总统←先当州长←竞选州长要有钱←那得找个有钱妹子←妹子都喜欢明星←身材好能当明星←健身 递归,就像一个人对自己的发展有清晰的规划和坚定的信心一样,他知道每一步会有怎么样的结果,他需要仅