排序——归并排序

四、归并排序

  1、基本思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

  2、实例

  3、java实现

复制代码
package com.sort;

//稳定
public class 归并排序 {
public static void main(String[] args) {
int[] a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};
System.out.println("排序之前:");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
//归并排序
mergeSort(a,0,a.length-1);
System.out.println();
System.out.println("排序之后:");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
}

private static void mergeSort(int[] a, int left, int right) {
if(left<right){
int middle = (left+right)/2;
//对左边进行递归
mergeSort(a, left, middle);
//对右边进行递归
mergeSort(a, middle+1, right);
//合并
merge(a,left,middle,right);
}
}

private static void merge(int[] a, int left, int middle, int right) {
int[] tmpArr = new int[a.length];
int mid = middle+1; //右边的起始位置
int tmp = left;
int third = left;
while(left<=middle && mid<=right){
//从两个数组中选取较小的数放入中间数组
if(a[left]<=a[mid]){
tmpArr[third++] = a[left++];
}else{
tmpArr[third++] = a[mid++];
}
}
//将剩余的部分放入中间数组
while(left<=middle){
tmpArr[third++] = a[left++];
}
while(mid<=right){
tmpArr[third++] = a[mid++];
}
//将中间数组复制回原数组
while(tmp<=right){
a[tmp] = tmpArr[tmp++];
}
}
}
复制代码
  4、分析

  归并排序是稳定的排序方法。

  归并排序的时间复杂度为O(nlogn)。

  速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列。

时间: 2024-08-27 04:30:57

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

插入排序 | 冒泡排序 | 希尔排序 | 堆排序 | 快速排序 | 选择排序 | 归并排序

以下是最近学习各种算法的代码实现: #include <stdlib.h> #include <stdio.h> #include <time.h> #include <limits.h> typedef int EleType; typedef int (*CompFunc)(void *,void *); int IntComp(void * a,void *b) { if(*(int *)a > *(int *)b) return 1; if(*

如何给10^7个数据量的磁盘文件进行排序--归并排序

接上面的题目,假若待排序的数据有重复的呢?这里采用的是归并排序. 1.算法分析:     1.稳定性:归并排序是一种稳定的排序.    2.存储结构要求:可用顺序存储结构.也易于在链表上实现.    3.时间复杂度: 对长度为n的文件,需进行lgn趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)..    4.空间复杂度:需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序. 2.总结 与快速排序相

数据结构排序-归并排序

归并排序是建立在归并操作上的一种有效的排序算法,时间复杂度是O(nlogn). 它过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1:否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元,如下图所示. 1 #include <stdio.h> 2 #include <stdlib.h&g

排序 归并排序 分配排序

归并排序          基本思想:将两个或两个以上的有序子序列"归并"为一个有序子序列.在内部排序中,通常采用的是2-路归并排序,即将两个位置相邻的有序子序列"归并"为一个有序序列.类似于快排,其使用的也是分治的策略. 二路归并排序 基本思想:将有n个记录的原始序列看做n个有序子序列,每个子序列的长度为1,然后从第1个子序列开始,把相邻的子序列两两合并,得到n/2个长度为2或1的子序列(当子序列的个数为奇数是,最后一组合并得到的序列长度为1),我们把这一过程称为

排序——归并排序(分治法)

在写归并排序之前,首先谈一谈分治的思想, 所谓分治:就是将一个比较复杂的问题分解为若干个规模较小的但是类似原问题的子问题,(解决)递归地求解这些这些子问题,再合并这些子问题的解来求解原问题 可分为三步: 分解:将原问题分解为若干个规模较小的但是类似原问题的子问题 求解:递归地求解这些这些子问题,然而若子问题规模足够小,可直接求解 合并:合并这些子问题的解来求解原问题 接下来,终于可以写归并排序了 分解:将一个有N个数的数列分解为2个分别有n/2个数的2个子数列 求解:使用归并排序递归地分别排序两

经典排序—归并排序思想及实现

归并排序(Merge)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用. 将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序.若将两个有序表合并成一个有序表,称为2-路归并.归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))的

高速排序 归并排序的非递归版本号 备忘

首先,归并排序,分治.递归解决小的范围.再合并两个有序的小范围数组,便得到整个有序的数组. 这是非常适合用递归来写的.至于非递归.便是从小到大.各个击破,从而使得整个数组有序.代码例如以下: void merge(vector<int> &A, int left, int mid, int right) { int i=left,j=mid+1; vector<int> tmp(right-left+1,0); int k=0; while(i<=mid&&a

单链表排序--归并排序

#include <iostream> #include <cstdlib> using namespace std; struct ListNode //默认为public { int data; ListNode* next; ListNode(int x, ListNode* nextNode):data(x), next(nextNode){} }; ListNode* mergeData(ListNode* first, ListNode* second) { if(fi

排序—归并排序

归并排序算法可以递归的描述为:算法将数组分为两半,对每部分递归地应用归并排序.在两部分都排好序后,对它们进行归并. package ss.sort; /** * 归并排序 * @author zhangss 2016-4-26 14:06:04 * */ public class MergeSort { /** * @param args */ public static void main(String[] args) { int[] list = {2, 3, 2, 5, 6, 1, -2,