算法-归并排序

归并排序是建立在归并操作上的一种有效的排序算法,算法主要采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序的算法复杂度为O(N*logN),需要的额外的空间跟数组的长度N有关系,实现归并排序最简单的方法是将两个数组重新整合到第三个数组中。通常对于一个数组我们对前半部分进行排序,然后惊醒后半部分进行排序,实现原地归并操作,不过需要额外的空间存储数组。假设数据中有8个元素,先分为四组进行比较,之后分为两组进行比较,最后分为一组进行比较,这样就衍生出来两种方法,一种是自顶向下的归并排序,一种是自底向上的归并排序。

自顶向下的归并排序

实现起来比较简单,不过merge的稍微麻烦点:

-(void)mergeSort:(NSMutableArray *)arr   lowIndex:(NSInteger)low highIndex:(NSInteger)high{
    if (high<=low) {
        return;
    }
    NSInteger mid=low+(high-low)/2;
    [self mergeSort:arr lowIndex:low highIndex:mid];//左半部分排序
    [self mergeSort:arr lowIndex:mid+1 highIndex:high];//右半部分排序
    [self merge:arr lowIndex:low highIndex:high midIndex:mid];

}

merge操作,就是对数组进行比较:

-(void)merge:(NSMutableArray *)dataSource  lowIndex:(NSInteger)low highIndex:(NSInteger)high  midIndex:(NSInteger)mid{
    NSInteger i=low,j=mid+1;

    for (NSInteger k=low; k<=high; k++) {
        self.tempArr[k]=dataSource[k];
    }
    for (NSInteger k=low; k<=high; k++) {
        //左边的元素已经取完,取右半边的元素
        if (i>mid) {
            dataSource[k]= self.tempArr[j++];
        }
        //右边的元素已经取完,取左边的元素
        else if (j>high) {
            dataSource[k]= self.tempArr[i++];
        }
        //如果索引j的值大,那么取左边的值
        else if ([self.tempArr[j] integerValue]<[self.tempArr[i] integerValue]) {
            dataSource[k]=self.tempArr[j++];
        }

        else{
            dataSource[k]=self.tempArr[i++];
        }
    }
}

 合并的时候需要给临时数组赋值:

        MySort  *sort=[[MySort alloc]init];
        NSMutableArray *tempArr=[[NSMutableArray alloc]initWithCapacity:10];
        for (NSInteger i=0; i<8; i++) {
            [tempArr addObject:[NSNull null]];
        }
        NSMutableArray *arr=[[NSMutableArray alloc]initWithCapacity:10];
        [arr addObject:@"16"];
        [arr addObject:@"3"];
        [arr addObject:@"2"];
        [arr addObject:@"18"];
        [arr addObject:@"19"];
        [arr addObject:@"10"];
        [arr addObject:@"4"];
        [arr addObject:@"25"];
        sort.tempArr=tempArr;
        [sort mergeSort:arr lowIndex:0 highIndex:arr.count-1];
        for (NSInteger i=0; i<[arr count]; i++) {
            NSLog(@"数值:%@",arr[i]);
        }
        NSLog(@"iOS技术交流群:%@",arr[2]);
        NSLog(@"原文地址:http://www.cnblogs.com/xiaofeixiang");

 效果如下:

自底向上的归并排序

自底向上的归并排序其实逻辑跟上一个一样,不过这个不需要递归到最后,直接从一开始就进行比较,通过控制增量解决合并的问题,如果有8个元素,增量为1时有四组(每组两个)合并,增量为2时候,两组(每组四个)合并,最后进行全部合并,代码比较简单:

-(void)mergeSortBottom:(NSMutableArray *)arr{
    NSInteger count=[arr count];
    for (NSInteger increment=1; increment<count; increment=increment+increment) {//增量的数组
        for (NSInteger low=0; low<count-increment; low+=increment+increment) {//每个增量比较的次数
            NSInteger high=(low+increment+increment-1)<(count-1)?(low+increment+increment-1):(count-1);
            [self merge:arr lowIndex:low highIndex:high midIndex:low+increment-1];
        }
    }
}

  各位,粽子节快乐~

时间: 2024-10-10 14:43:23

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

排序算法——归并排序

归并排序是分治法的典型举例. 分治法的思想是,将原有问题分解为几个规模较小但类似于原问题的子问题,递归的求解这些子问题,然后再合并这些子问题的解来建立原问题的解. 分治模式在每层递归时都有三个步骤: 分解原问题为若干子问题,这些子问题是原问题的规模较小的实例. 解决这些子问题,递归地求解各子问题.然而,若子问题的规模足够小,则直接求解. 合并这些子问题的解成原问题的解. 归并排序算法完全遵循分治模式.直观上其操作如下: 分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列. 解决:使用

经典排序算法 - 归并排序Merge sort

经典排序算法 - 归并排序Merge sort 原理,把原始数组分成若干子数组,对每个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到所有合并完,形成有序的数组 举例 无序数组[6 2 4 1 5 9] 先看一下每一个步骤下的状态,完了再看合并细节 第一步 [6 2 4 1 5 9]原始状态 第二步 [2 6] [1 4] [5 9]两两合并排序,排序细节后边介绍 第三步 [1 2 4 6] [5 9]继续两组两组合并 第四步 [1 2 4 5 6 9]合并完成,排序完成 输出结

Java实现算法归并排序(MergeSort)

归并排序 归并排序 (merge sort) 是一类与插入排序.交换排序.选择排序不同的另一种排序方法.归并的含义是将两个或两个以上的有序表合并成一个新的有序表.归并排序有多路归并排序.两路归并排序 , 可用于内排序,也可以用于外排序.这里仅对内排序的两路归并方法进行讨论. 1.两路归并排序算法思路 ①把 n 个记录看成 n 个长度为1的有序子表: ②进行两两归并使记录关键字有序,得到 n/2 个长度为 2 的有序子表: ③重复第②步直到所有记录归并成一个长度为 n 的有序表为止. 实例: 2.

[算法]——归并排序(Merge Sort)

归并排序(Merge Sort)与快速排序思想类似:将待排序数据分成两部分,继续将两个子部分进行递归的归并排序:然后将已经有序的两个子部分进行合并,最终完成排序.其时间复杂度与快速排序均为O(nlogn),但是归并排序除了递归调用间接使用了辅助空间栈,还需要额外的O(n)空间进行临时存储.从此角度归并排序略逊于快速排序,但是归并排序是一种稳定的排序算法,快速排序则不然. 所谓稳定排序,表示对于具有相同值的多个元素,其间的先后顺序保持不变.对于基本数据类型而言,一个排序算法是否稳定,影响很小,但是

我实现的第一个算法----归并排序

今天听了卜东坡老师的算法课,讲的是归并算法,那个动画演示,终于让我开窍了,于是乎,赶紧今天就编了个C++的程序.我知道可能这个程序还比较粗糙,但是这是第一次实现了算法导论上的东东,心里那个激动啊,,,哎,我也终于能实现个算法了,以前总认为自己很菜,其实真的很菜,,,算了,直接上程序吧,,, #include<iostream> using namespace std; int a[100]; int flag; int n; void vector_initial(); void print_

算法--归并排序(链表)

归并排序 http://blog.csdn.net/morewindows/article/details/6678165 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 归并操作: http://www.tuicool.com/articles/iy2QRn6 归并操作 归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法. 如:设有数列 [6,202,100,301,38,8,1]

python数据结构与算法——归并排序

归并排序: 原理与C语言实现 参考:白话经典算法系列之五 归并排序的实现 1. 容易对有序数组A,B进行排序. 2. 为了使得A,B组内数据有序:可以将A,B组各自再分成二组. 3. 经过不断分组,当分出来的小组只有一个数据时(有序),合并相邻二个小组. 这样通过先递归的分解数列,再合并数列就完成了归并排序. 代码摘自<Python Algorithm> 1 # 对数组seq进行归并排序 2 # 返回排序后数组 3 def mergesort(seq): 4 mid = len(seq)//2

算法—归并排序的改进及排序算法的极致

1.对小规模子数组使用插入排序 用不同的方法处理小规模问题能改进大多数递归算法的性能,因为递归会使小规模问题中方法的调用过于频繁,所以改进对它们的处理方法就能改进整个算法.对排序来说,我们已经知道插入排序(或者选择排序)非常简单,因此很可能在小数组上比归并排序更快.和之前一样,一幅可视轨迹图能够很好地说明归并排序的行为方式.图中的可视轨迹图显示的是改良后的归并排序的所有操作.使用插入排序处理小规模的子数组(比如长度小于15)一般可以将归并排序的运行时间缩短10%~15%. 2.测试数组是否已经有

[经典算法] 归并排序

题目说明: 归并排序是建立在归并操作上的一种有效的排序算法.该算法也是采用分治法(Divide and Conquer)的一个非常典型的应用.算法复杂度为O(N*logN). 题目解析: 归并排序是利用递归和分而治之的技术将数据序列划分成为越来越小的半子表,再对半子表排序,最后再用递归步骤将排好序的半子表合并成为越来越大的有序序列. 归并排序包括两个步骤: 1)划分子表 2)合并半子表 伪代码: 合并排序伪代码(使用哨兵): merge(A,p,q,r): n1 <-- q-p+1 n2 <-