归并排序

Contest100000586 - 《算法笔记》4.6小节——算法初步->two pointers

大憨熊 提交于 2019-12-27 00:43:45
常用模板 two pointers:利用问题本身与序列的特性,使用两个下标 i,j 对序列进行扫描(可以同向扫描,也可以反向扫描),以较低的复杂度(一般是 O ( n ) O(n) O ( n ) )解决问题。 定和问题 给定一个 递增 的 正整数序列 和一个正整数M,求序列中的两个 不同位置 的数a和b,使得它们的和恰好为M,输出 所有 满足条件的方案。 模板如下: while ( i < j ) { if ( a [ i ] + a [ j ] == m ) { cout << i << ' ' << j ; ++ i ; -- j ; } else if ( a [ i ] + a [ j ] < m ) ++ i ; else -- j ; } 由于 i 的初值为0,j 的初值为n - 1(i,j 分别指向序列的第一个和最后一个元素),而 i 只递增,j 只递减,循环当 i >= j 时停止,因此 i 和 j 的操作最多为n次。即时间复杂度为 O ( n ) O(n) O ( n ) 。 序列合并问题 假设有两个递增序列A与B,要求将它们合并为一个递增序列C。设置两个下标 i 和 j,初值均为0,分别指向序列A和序列B的第一个元素。 int Merge ( int A [ ] , int B [ ] , int C [ ] , int n , int m ) { int i

八种常用排序算法 - C语言

狂风中的少年 提交于 2019-12-26 22:58:51
文章目录 数据结构之排序算法 一、 实验目的 二、 实验内容 三、 实验工具 四、 实验代码 五、 实验结果 六、 总结与思考 数据结构之排序算法 一、 实验目的 了解排序的相关概念,理解各种排序方法的思想与排序过程,掌握各种排序方法的时间复杂度分析,实现各种排序算法。 二、 实验内容 通过编写程序,实现希尔排序、快速排序、堆排序和归并排序等算法。具体步骤如下: 在主函数中输入线性序列和关键字; 创建实现希尔排序、快速排序、堆排序和归并排序的子函数; 在主函数中,通过switch语句调用相关函数,实现排序。 三、 实验工具 Dev - C++ 四、 实验代码 //Authors:xiaobei # include <stdio.h> # include <stdlib.h> # define MAXSIZE 20 typedef int KeyType ; typedef char InfoType ; typedef struct { KeyType key ; InfoType otherinfo ; } RedType ; typedef struct { RedType r [ MAXSIZE + 1 ] ; int length ; } SqList ; //函数创建顺序表 int CreateSq ( SqList & L ) { int i , length ;

归并排序——“递归+合并”(Java版)

谁说胖子不能爱 提交于 2019-12-25 21:47:19
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。 首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。 // 将有序数组a[]和b[]合并到c[]中 三个while循环 public static void megerArray(int[] a, int n, int[] b, int m, int[] c) { int i = 0, j = 0, k = 0; while (i < n && j < m) { if (a[i] < b[j]) { c[k++] = a[i++]; } else { c[k++] = b[j++]; } } while (i < n) { c[k++] = a[i++]; } while (j < m) { c[k++] = b[j++]; } } 可以看出合并有序数列的效率是比较高的,可以达到O(n)。 解决了上面的合并有序数列问题,再来看归并排序,其的基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序

js算法:Merge Sort 归并排序

我的未来我决定 提交于 2019-12-25 21:28:45
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> Merge Sort : 归并排序,把一个大问题分解成若干相同的小问题,解决小问题后,合并小问题结果,最终把大问题解决. 例如要排序数组 originArr = [2, 5, 3, 8, 9, 6, 3, 4, 2] 先把问题分解为排序 leftArr = [2, 5, 3, 8, 9] 和 rightArr = [6, 3, 4, 2]两个小数组,然后合并leftArr和rightArr,当排序leftArr的时候发现问题还是太复杂, 再把leftArr分解为 leftArr1 = [2, 5, 3] 和 rightArr1 = [8, 9] ...以此递归调用,直到 leftArrN = [2]... //分治法排序 var originArr = [2, 5, 3, 8, 9, 6, 3, 4, 2] let startTime = new Date().valueOf(); console.info("原始数组:", originArr) function mergeSort(arr, from, to) { //寻找合适的分割点 let mid = parseInt((to + from) / 2); if (to > from) { //如果 to!= from 说明问题还是太复杂,递归调用分解问题

归并排序

拟墨画扇 提交于 2019-12-25 19:43:59
归并排序 归并排序是建立在归并操作上的一种有效的排序算法,是采用分治法的一个典型应用。其时间复杂度为O(n log n) 归并排序的步骤如下: 划分求解 :将序列分成元素个数尽量相等的两半。 递归求解 :将两半元素分别排序。 合并问题 :将两个有序表合并在一起 当我们要排序一个数组的时候,归并排序法首先将这个数字分成一半,然后给左边的数组排序,右边的数组给排序,之后将它们归并起来,而我们在对左边和右边的数组排序的时候,又可以将它们继续划分成一半,然排序,归并,如此递归,到一定程度的时候,我们就将这个数组分成了一个又一个的元素,此时不用排序,对它们进行一次简单的归并就可以 例;将8,6,2,3,1,5,7,4进行排序。 ​ 先将数组进行划分,依次划分后如图所示 ​ 然后进行第一次排序归并,如图所示 ​ 依次归并 ​ 直至最后一次归并完成 对于两个数组的归并,我们可以开一个临时数组来辅助我们归并,然后两个指针分别扫两个数组,按照大小归于辅助数组 具体代码实现如下 /*******************************归并算法*****************************/ #include<stdio.h> #include<string.h> #define ll long long const ll maxn = 600000 + 5; ll ans = 0;

【排序算法】No.2 归并排序

谁都会走 提交于 2019-12-22 17:01:23
时间复杂度:O(NlogN) 空间复杂度:O(N) public void merge(int[] array, int left, int mid, int right) { int length = right - left + 1; int[] tmp = new int[length]; int i = left, j = mid + 1, index = 0; while (i <= mid && j <= right) { if (array[i] <= array[j]) { tmp[index++] = array[i++]; } else { tmp[index++] = array[j++]; } } while (i <= mid) { tmp[index++] = array[i++]; } while (j <= right) { tmp[index++] = array[j++]; } for (i = 0; i < length; i++) { array[left++] = tmp[i]; } } public void mergeSort(int[] array, int left, int right) { if (left >= right) { return; } int mid = (left + right) / 2; mergeSort

归并排序

梦想与她 提交于 2019-12-22 09:38:42
归并:将两个或两个以上的有序序列合并成一个有序序列的过程。 归并排序的主要操作是归并,其主要思想是:将若干有序序列逐步归并,最终得到一个有序序列。 基本思想: 将一个具有n个待排序记录的序列看成是n个长度为1的有序序列, 然后进行两两归并, 得到n/2个长度为2的有序序列, 再进行两两归并,得到n/4个长度为4的有序序列, ……, 直至得到一个长度为n的有序序列为止。 void Merge ( int r [ ] , int r1 [ ] , int s , int m , int t ) { i = s ; j = m + 1 ; k = s ; while ( i <= m && j <= t ) { if ( r [ i ] <= r [ j ] ) r1 [ k ++ ] = r [ i ++ ] ; else r1 [ k ++ ] = r [ j ++ ] ; } if ( i <= m ) while ( i <= m ) //收尾处理 r1 [ k ++ ] = r [ i ++ ] ; //前一个子序列 else while ( j <= t ) r1 [ k ++ ] = r [ j ++ ] ; //后一个子序列 } void MergePass ( int r [ ] , int r1 [ ] , int n , int h ) { i = 1 ; /

归并排序

那年仲夏 提交于 2019-12-22 01:19:05
没有几个写归并排序的dalao? 我翻了好几页,就看到一位dalao写了归并排序,而且没有任何说明和注释 ,也有可能是我眼睛不好使,望各位dalao和管理见谅 本来要写逆序对这个题,然后来这里先联系一下归 龟 排 归并排序利用的是分治思想 假如有两个已经排好序的序列,你怎么合并他们? 举个例子吧,我们搞两个指针l和r,初始时令他们=各自序列第一个数的位置 1 4 10 2 11 15 那么a[l] 就等于1,a[r]就等于2 (1)首先a[l] < a[r] 我们将a[l]加入另一个待选数列t[] = {1}; 然后l++ (2)现在a[l] > a[r] 把a[r]加入t[] = {1,2} 然后r++ (3)然后a[l] < a[r] a[l] 加入t[] = {1,2,4} l++ (4)a[l] < a[r] a[l] 加入t[] = {1,2,4,10} ,然后l++ 我们现在发现l > 第一个数组的长度,代表第一个数组的最大值也不如a[r] 及a[r]之后的数大,所以把剩下数全加进去 最终t[] = {1,2,4,10,11,15} 那么我们怎么得到两个有序的数列呢? 我们发现,如果一个数列只有一个数,那么它是有序的,这样我们就可以递归解决问题,递归到1就返回,因为已经排好了 以上就是龟排的过程 #include<bits/stdc++.h> //万能头 using

数据结构实验之排序五:归并求逆序数 SDUT 3402

人盡茶涼 提交于 2019-12-21 09:42:34
Problem Description 对于数列a1,a2,a3…中的任意两个数ai,aj (i < j),如果ai > aj,那么我们就说这两个数构成了一个逆序对;在一个数列中逆序对的总数称之为逆序数,如数列 1 6 3 7 2 4 9中,(6,4)是一个逆序对,同样还有(3,2),(7,4),(6,2),(6,3)等等,你的任务是对给定的数列求出数列的逆序数。 Input 输入数据N(N <= 100000)表示数列中元素的个数,随后输入N个正整数,数字间以空格间隔。 Output 输出逆序数。 Sample Input 10 10 9 8 7 6 5 4 3 2 1 Sample Output 45 # include <stdio.h> # include <string.h> long long a [ 100005 ] , t [ 100005 ] , re ; void add ( long long s1 , long long e1 , long long s2 , long long e2 ) { long long top , num1 , num2 , num , i ; top = 0 ; num1 = s1 ; num2 = s2 ; while ( num1 <= e1 && num2 <= e2 ) { if ( a [ num1 ] <= a [

链表的归并排序

ⅰ亾dé卋堺 提交于 2019-12-18 00:31:35
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *getmid(ListNode *head) {   ListNode *p=head;   ListNode *q=p->next;   while(q!=NULL&&q->next!=NULL)//q每次走两个,p走一个,开始时p在第一个节点,q在第二个节点   {   p=p->next;   q=q->next->next;   } return p; } ListNode * mergeList(ListNode *&l1,ListNode *&l2)//合并两个有序的链表 {   if(l1==NULL)     return l2;   if(l2==NULL)     return l1;   ListNode *head=new ListNode(0);//新建一个头结点,用于存储归并后的链表   ListNode *p=head;   while(l1!=NULL && l2!=NULL)   {   if(l1-