`
SCYForce
  • 浏览: 40822 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

算法笔记(第一部分)-- 排序之白话归并排序

阅读更多
归并排序是一种基于比较的排序算法,在多数的实现方法下它是稳定的。归并排序可是由计算机祖师级人物-冯 诺依曼提出的哦。

归并排序的过程:
1. 如果数据链表的长度为0或1,则返回
2. 将原始数据链表对半分成两个子链表
3. 对每个子链表递归的调用合并排序进行排序
4. 合并两个子链表使其成为一个排序完成的链表

归并排序的时间复杂度为О(nlogn),空间复杂度为О(n)

归并排序的动画:


归并排序代码-mergesort:
public int[] mergeSort(int[] data){
        if(data.length<=1)
              return data;
        int middle = data.length/2;
        int[] left = new int[middle];
        int[] right = new int[data.length-middle];
        for(int i=0; i<left.length; i++){
              left[i] = data[i];
        }
        for(int i=0; i<right.length;i++){ 
        	right[i] = data[middle+i];
        }
        left = mergeSort(left);
        right = mergeSort(right);
        int[] result = merge(left, right);
        return result;
    }
public int[] merge(int[] left,int[] right){
        int result[] = new int[left.length + right.length];
        int index = 0;//index of result
        int x = 0;//index of left
        int y = 0;//index of right 

        //compare each element in two arrays, after comparing, index++.
        while(x<left.length && y<right.length){
              if(left[x]<right[y]){
                    result[index++] = left[x++];
              }else{
                    result[index++] = right[y++];
              }
        }
       
        //the length of two arrays might be different, 
        //so we have to copy the rest elements in two arrays
        while(x<left.length)  
              result[index++] = left[x++];  
        while(y<right.length)  
              result[index++] = right[y++];
        return result;
  }


归并排序的示意图:


由以上示意图可以看出mergesort的过程很简单,白话一点就是:拆分拆分拆分直至每个链表中仅有一个元素,合并合并合并至最终排好序的链表。merge是核心,经过递归调用归并排序后产生的left与right是已经排好序的两个子链表,依次比较left与right中的两数,将其放入适当的位置,然后删除子链表中已经放入result的那个数,最后将left与right中剩余的数依次放入result。问题:在实现的算法中,每次都要产生很多临时的list,这样效率是不是不高?

另曾经去一家小公司面试,工程师出了一道题:给定两个排好序的数组,如何将其合并是新的数组依然有序,似乎就是归并排序的应用,我的答案:

public int[] merge(int[] left,int[] right){
            int result[] = new int[left.length + right.length];
            int index = 0;//index of result
            int x = 0;//index of left
            int y = 0;//index of right 

            //compare each element in two arrays, after comparing, index++.
            while(x<left.length && y<right.length){
                  if(left[x]<right[y]){
                        result[index++] = left[x++];
                  }else{
                        result[index++] = right[y++];
                  }
            }
           
            //the length of two arrays might be different, 
            //so we have to copy the rest elements in two arrays
            while(x<left.length)  
                  result[index++] = left[x++];  
            while(y<right.length)  
                  result[index++] = right[y++];
            return result;
      }


代码的思想:将两个数组中的每一个数经过比较填入结果数组,由于可能两个数组的长度不等,最后还要将那个数组中剩余的数填入结果数组。
11
1
分享到:
评论
3 楼 cy729215495 2008-10-08  
我仔细的把你的算法研究了一遍,发现有点问题,本来算法是要求把一个数组最后分成零散的一个一个的,你的二次递归方法完全是没有必要的,更重要的是left和right并不是紧挨的两个元素在归并,不如直接取这个data里面的两个紧挨着的元素比较,不需要递归。欢迎和我探讨 ,我qq:729215495
2 楼 litianyi520 2008-09-08  
package java.util.Arrays;
里面的sort方法 好像也是冒泡排序,

private static void sort1(int x[], int off, int len) {
// Insertion sort on smallest arrays
if (len < 7) {
    for (int i=off; i<len+off; i++)
for (int j=i; j>off && x[j-1]>x[j]; j--)
    swap(x, j, j-1);
    return;
}

swap 方法 和c的写法一样
   private static void swap(long x[], int a, int b) {
long t = x[a];
x[a] = x[b];
x[b] = t;
    }
1 楼 farryu 2008-09-03  
lz的算法一看就知道是原创的,呵呵,很值得佩服,不过建议lz可以看看collection包中Arrays的sort的归并排序,可用性比较高

相关推荐

    MoreWindows白话经典算法之七大排序

    冒泡排序、插入排序、选择排序、希尔排序、归并排序、快速排序和堆排序是七大基础的计算机算法,它们各自有着不同的特点和适用场景。 一、冒泡排序(Bubble Sort) 冒泡排序是一种简单的排序算法。它重复地遍历要...

    MoreWindows白话经典算法之七大排序第2版(高清)

    本书《更多Windows白话经典算法之七大排序第2版》是一部深入浅出讲解七种经典排序算法的著作,旨在帮助读者理解并掌握冒泡排序、直接插入排序、直接选择排序、希尔排序、归并排序、快速排序以及堆排序等基本概念和...

    MoreWindows白话经典算法之七大排序(高清版)

    ### 白话经典算法之七大排序 #### 一、冒泡排序 冒泡排序是一种简单直观的排序算法,它的基本思想是从第一个元素开始,比较相邻元素的大小,如果前一个元素大于后一个元素则交换它们的位置,这样一轮比较下来,...

    白话经典算法之七大排序

    归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。 快速...

    白话经典算法之七大排序(高清版)

    《白话经典算法之七大排序》是一本专为初学者设计的算法教程,旨在通过简单易懂的语言,帮助读者深入浅出地理解并掌握七大排序算法。这些排序算法是计算机科学与信息技术领域的基础,对于提升编程能力和解决实际问题...

    排序算法经典讲解

    本资源"MoreWindows白话经典算法之七大排序(高清版).pdf"提供了一套详尽的排序算法讲解,涵盖了七大经典的排序算法。以下是这些排序算法的详细介绍: 1. 冒泡排序(Bubble Sort): 冒泡排序是一种简单的交换排序,...

    经典算法之七大排序白话讲解第二版

    以上就是对直接选择排序、希尔排序、归并排序、快速排序以及堆排序这五大经典排序算法的介绍。每种排序算法都有其特点和应用场景,了解它们的工作原理可以帮助我们在实际编程中做出更加合理的选择。接下来的文章中将...

    白话经典算法系列之六 快速排序 快速搞定 - MoreWindows - 博客园1

    快速排序是一种高效的排序算法,由C.R.A.Hoare在1962年提出。它基于分治策略,但其完整流程可以更准确地描述为“挖坑填数+分治法”。快速排序的核心思想是通过选取一个基准数,将数组分为两部分:一部分的所有元素都...

    [网盘]MoreWindows白话经典算法之七大排序第2版(高清)

    在第一版的基础上新加了对冒泡排序,直接插入排序,直接选择排序,希尔排序,归并排序,快速排序和堆排序这七种常用的排序方法的总结篇,方便大家复习,合适作为笔试面试前的复习资料。

    基于python 3 编程实现常用的排序算法,包括:冒泡排序、直接插入排序、直接选择排序、希尔排序、归并排序、快速排序、堆排序

    基于python 3 编程实现常用的排序算法,包括:冒泡排序、直接插入排序、直接选择排序、希尔排序、归并排序、快速排序、堆排序.zip 基于python 3 编程实现常用的排序算法,包括:冒泡排序、直接插入排序、直接选择...

    白话经典算法

    本文将详细解析七种经典的排序算法:冒泡排序、直接插入排序、直接选择排序、希尔排序、归并排序、快速排序以及堆排序。这些算法对于程序员来说至关重要,无论是在日常开发还是在面试中,都是常被问及的知识点。 1....

    More Windows白话经典数据结构算法之七大排序最新整理版

    ### 数据结构与排序算法详解 ...当数据量较大时,这两种算法的性能会下降,此时应考虑使用更高效的排序算法,如快速排序、归并排序等。在实际应用中,了解各种排序算法的特点,选择最适合当前场景的算法至关重要。

    白话的排序总结

    1. 初始化:假设数组的第一个元素已经是排序好的。 2. 遍历:从未排序的部分取一个元素,与已排序的部分进行比较,找到正确的位置插入。 3. 重复:继续从未排序的部分取出下一个元素,重复以上过程,直到所有元素都...

    白话算法(理论联系实际)-初探遗传算法接近完美

    1. **种群**:遗传算法的起点是一个包含多个解(个体)的集合,每个个体都有一个与之相关的适应度值,这通常反映了该解的质量或性能。 2. **基因编码**:个体的基因编码是问题解决方案的表示方式,可以是二进制串、...

    最短路径算法—Bellman-Ford(贝尔曼-福特)算法分析与实现(CC++)

    最短路径算法—Bellman-Ford(贝尔曼-福特)算法分析与实现(CC++),希望对你能有所帮助!

    数据结构和算法必知必会的50个代码实现

    * 实现一个有序数组的二分查找算法* 实现模糊二分查找算法(比如大于等于给定值的第一个元素) ## 散列表* 实现一个基于链表法解决冲突问题的散列表* 实现一个LRU缓存淘汰算法 ## 字符串 ## 二叉树 ## 堆 ## 图 ##...

Global site tag (gtag.js) - Google Analytics