归并排序

3月5日笔记

若如初见. 提交于 2020-03-11 03:21:07
3月5日学习 一、算法学习 1、归并排序 2、堆排序 一、算法学习 1、归并排序 代码 : # include <iostream> # include <string> # include <cstring> # include <algorithm> # include <memory> # include <functional> using namespace std ; void merge ( int a [ ] , int l , int mid , int r ) { //cout<<"l:"<<l<<endl; //cout<<"r:"<<r<<endl; //cout<<"mid:"<<mid<<endl; int help [ 100 ] ; int p1 = l ; int p2 = mid + 1 ; int i = 0 ; while ( p1 <= mid && p2 <= r ) { if ( a [ p1 ] <= a [ p2 ] ) { help [ i ++ ] = a [ p1 ++ ] ; } else { help [ i ++ ] = a [ p2 ++ ] ; } } while ( p1 <= mid ) { help [ i ++ ] = a [ p1 ++ ] ; } while ( p2 <= r ) { help [ i

分治思想与归并排序

主宰稳场 提交于 2020-03-09 22:00:04
分治法 的思想: 将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些自问题,然后再合并这些自问题的解来建立原问题的解。 分支模式在每层递归时都有三个步骤: 分解 原问题为若干子问题,这些子问题是原问题的规模较小的实例。 解决 这些子问题,递归地求解各子问题。然而,若子问题的规模足够小,则直接求解。 合并 这些子问题的解成原问题的解。 归并排序 算法完全遵循分治模式。直观上其操作如下: 分解: 分解待排序的n个元素的序列成各具n/2个元素的两个子序列。 解决: 使用归并排序递归地排序两个子序列。 合并: 合并两个已排序的子序列以产生已排序的答案。 参考: 《算法导论》中文版原书第3版Page16,17 来源: https://www.cnblogs.com/drfxiaoliuzi/p/5892158.html

归并排序

大兔子大兔子 提交于 2020-03-09 21:59:06
分治法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归求解这些子问题,然后再合并这些子问题的解来建立原问题的解。主要包括三个主要步骤:1、分解原问题 ;2、解决子问题;3、合并子问题的解 归并排序遵循分治模式,算法的时间复杂度是O(NlogN),属于稳定排序。直观操作为: 分解 :分解待排序的n个元素的序列成各具有n/2个元素的两个子序列。 解决 :使用归并排序递归地排序两个子序列。 合并 :合并两个已排序的子序列以产生已排序的答案。 具体算法由一个辅助函数和一个递归函数组成: 函数代码: #include<iostream> using namespace std; #define INF 65535 template<class T> void Merge(T *A, int p, int q, int r) { int n1 = q - p + 1; int n2 = r - q; T *L = new T[n1 + 1]; T *R = new T[n2 + 1]; for (int i = 0; i<n1; i++){ L[i] = A[p + i]; } for (int j = 0; j<n2; j++){ R[j] = A[q + j + 1]; } L[n1] = INF; R[n2] = INF; int i = 0,j = 0; for (int

归并排序&&归并排序求逆序对

眉间皱痕 提交于 2020-03-08 08:22:00
归并排序 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 算法: 第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置 第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针超出序列尾 将另一序列剩下的所有元素直接复制到合并序列尾 import java.util.*; public class Main1 { static int a[] = new int[10010]; static int b[] = new int[10010]; public static void sort(int a[], int l, int r) { if (r - l > 0) { int mid = (r + l) / 2; int i = l; int p = l; int q = mid + 1; sort(a, l, mid); sort(a, mid + 1, r); while (p <= mid || q

归并排序模板(Java)

两盒软妹~` 提交于 2020-03-07 03:54:12
import java.util.Scanner; import java.io.BufferedInputStream; class Main{ static int N = (int) 1e5 + 10,len; static int[] q = new int[N],temp = new int[N]; static void mergeSort(int[] q,int l,int r){ if(l>=r) return; int mid=(l+r)>>1; mergeSort(q,l,mid); mergeSort(q,mid+1,r); int k=0,i=l,j=mid+1; while(i<=mid&&j<=r) if(q[i]<q[j])temp[k++]=q[i++]; else temp[k++]=q[j++]; while(i<=mid) temp[k++]=q[i++]; while(j<=r)temp[k++]=q[j++]; for(k=0,i=l;i<=r;++i,++k) q[i]=temp[k]; } public static void main(String[] args){ Scanner sc=new Scanner(new BufferedInputStream(System.in)); len=sc.nextInt(); for(int

Java实现归并排序

最后都变了- 提交于 2020-03-06 12:32:12
百度百科:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路 归并 。 归并操作 : 归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。 如 设有数列{6,202,100,301,38,8,1} 初始状态:6,202,100,301,38,8,1 第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3; 第二次归并后:{6,100,202,301},{1,8,38},比较次数:4; 第三次归并后:{1,6,8,38,100,202,301},比较次数:4; 总的比较次数为:3+4+4=11; 逆序数为14 算法描述 归并操作的工作原理如下: 第一步:申请空间,使其大小为两个已经 排序 序列之和,该空间用来存放合并后的序列 第二步:设定两个 指针 ,最初位置分别为两个已经排序序列的起始位置 第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针超出序列尾 将另一序列剩下的所有元素直接复制到合并序列尾 图例: java代码实现: package

归并排序

主宰稳场 提交于 2020-03-06 12:31:13
归并操作 归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。 如 设有数列{6,202,100,301,38,8,1} 初始状态:6,202,100,301,38,8,1 第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3; 第二次归并后:{6,100,202,301},{1,8,38},比较次数:4; 第三次归并后:{1,6,8,38,100,202,301},比较次数:4; 总的比较次数为:3+4+4=11,; 逆序数为14; 算法描述 归并操作的工作原理如下: 第一步:申请空间,使其大小为两个已经 排序 序列之和,该空间用来存放合并后的序列 第二步:设定两个 指针 ,最初位置分别为两个已经排序序列的起始位置 第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针超出序列尾 将另一序列剩下的所有元素直接复制到合并序列尾 代码实现 func mergeSort(r []int) []int { length := len(r) if length <= 1 { return r } num := length / 2 left := mergeSort(r[:num]) right := mergeSort(r[num:]) return merge

归并排序(非递归)

拈花ヽ惹草 提交于 2020-03-06 12:24:53
  这次自己写了一下   总结起来就是:   归并排序递归和非递归形式是逆过程。   两者有的地方是一样的,不一样的地方是:   递归是递归拆分成一小段一小段的排序,同时是把A拆成A1 A2,先把A1整个排好,再排A2,最后达到排好整个A的目的。   非递归是序列从左往右先按等分的长度(i)逐个排好,长度不够i的在末尾,于是对它排一次序,然后让i两倍递增。 #include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX 1000 #define OK 1 #define ERROR 0 using namespace std; typedef struct { int t[MAX]; int a[MAX]; int length; }ma; void LoadList(ma &m) { int i; for(i=0;i<m.length;i++) printf("%d ",m.t[i]); printf("\n"); } void merge(ma &m,int x,int y,int mid) { int i,p,q; p=x,q=mid,i=x; while(p<mid || q<y) { if(q>=y || (p<mid && m.t[p]<=m.t[q])) m.a[i++]=m.t[p++];

归并排序(递归与非递归写法)

五迷三道 提交于 2020-03-06 12:23:40
本文同步发布在CSDN: https://blog.csdn.net/weixin_44385565/article/details/94588321 归并排序的基本操作是将两个有序数组合并成一个有序数组,原理是运用分治思想,递归地将一个数组的左右两部分有序数列进行归并。 C/C++的递归实现: 1 // mergeSort.cpp : 递归写法 2 // 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 #define elementType int//自定义数据类型 7 using namespace std; 8 9 void mergeSort(elementType A[], int N);//N为数组大小,统一函数接口 10 void mSort(elementType A[], elementType tmpA[], int L, int rightEnd);//传入左右边界 11 void merge(elementType A[], elementType tmpA[], int L, int R, int rightEnd);//将有序的两个部分进行归并 12 13 14 int main() 15 { 16 int N;//数组大小 17 scanf("%d", &N); 18 elementType* A =

非递归实现归并排序

|▌冷眼眸甩不掉的悲伤 提交于 2020-03-06 12:23:09
思想:利用的还是分治思想,只不过这次我们把数组以2的倍数划分,然后进行两两合并,划分代码如下: public static void merge(int[] arr){ for(int i = 1;i<arr.length;i *= 2){ mergeSort(arr,i); } } 合并代码如下: public static void mergeSort(int[] arr, int gap) { int[] tmp = new int[arr.length]; int index = 0; int start1 = 0; int end1 = start1 + gap - 1; int start2 = end1 + 1; int end2 = (start2 + gap - 1)>=arr.length?arr.length-1:start2+gap-1; while(start2<arr.length){ while(start1<=end1&&start2<=end2){ if(arr[start1]<arr[start2]){ tmp[index++] = arr[start1++]; }else{ tmp[index++] = arr[start2++]; } } while(start1<=end1){ tmp[index++] = arr[start1++]; }