两个相同类型已排序数据进行合并,虽然list数组中有AddRange方法,但它只是把第二个数组从第一个数组末尾插入,假如两个数组有重复数据,保存进去。
还有Union方法合并去重,首先会从第一个数组进行检查然后再把第二个数组数据从第一个数组依次从末尾插入,但相对于自定义类型排序还是不能有效解决问题。

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

归并过程为:比较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的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

Examples

 using System;
using System.Collections.Generic;
using System.Linq; namespace Examples.Utils
{
public static class CollectionUtils
{
public static IList<T> MergeSortedLists<T>(Comparison<T> comparision, IList<T> list1, IList<T> list2)
{
var mergedList = new List<T>(list1.Count + list2.Count);
int i = , j = ;
while (i < list1.Count && j < list2.Count)
{
var result = comparision(list1[i], list2[j]);
if (result <= )
{
if (result == )
{
j++;
}
mergedList.Add(list1[i++]);
}
else
{
mergedList.Add(list2[j++]);
}
}
while (i < list1.Count)
{
mergedList.Add(list1[i++]);
}
while (j < list2.Count)
{
mergedList.Add(list2[j++]);
}
return mergedList;
}
}
}

TestExamples

 using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework; namespace Examples.Utils.Tests
{
[TestFixture]
public class CollectionUtilsTests
{
[Test]
public void Merge2TestNoDuplicate()
{
var list1 = new List<int> {, , , , };
var list2 = new List<int> {, , , , };
var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
Assert.AreEqual(expectedList.Count, mergedList.Count);
CollectionAssert.AreEqual(expectedList, mergedList);
} [Test]
public void Merge2TestWithDuplicates()
{
var list1 = new List<int> {, , , , };
var list2 = new List<int> {, , , , };
var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
Assert.AreEqual(expectedList.Count, mergedList.Count);
CollectionAssert.AreEqual(expectedList, mergedList);
} [Test]
public void Merge2TestNoOverlap1()
{
var list1 = new List<int> {, , , , };
var list2 = new List<int> {, , , , };
var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
Assert.AreEqual(expectedList.Count, mergedList.Count);
CollectionAssert.AreEqual(expectedList, mergedList);
} [Test]
public void Merge2TestNoOverlap2()
{
var list1 = new List<int> {, , , , };
var list2 = new List<int> {, , , , };
var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
Assert.AreEqual(expectedList.Count, mergedList.Count);
CollectionAssert.AreEqual(expectedList, mergedList);
} private static IList<T> GetExpectedMergedList<T>(Comparison<T> comparision, params IList<T>[] lists)
{
var set = new SortedSet<T>(new ComparisionComparer<T>(comparision));
foreach (var list in lists)
{
foreach (var item in list)
{
if (!set.Contains(item))
{
set.Add(item);
}
}
}
return set.ToList();
} private static int IntegerComparision(int x, int y)
{
return y - x;
} private class ComparisionComparer<T> : IComparer<T>
{
private readonly Comparison<T> _comparision; public ComparisionComparer(Comparison<T> comparision)
{
_comparision = comparision;
} public int Compare(T x, T y)
{
return _comparision(x, y);
}
}
}
}

C#两路list数组归并去重的更多相关文章

  1. list数组归并去重

    C#两路list数组归并去重 个相同类型已排序数据进行合并,虽然list数组中有AddRange方法,但它只是把第二个数组从第一个数组末尾插入,假如两个数组有重复数据,保存进去.还有Union方法合并 ...

  2. 对两个有序数组重新去重合并排序js实现

    这里主要是要利用两个数组有序这个条件,所以只需两个指针分别指向两个数组,当其中一个小于另外一个就移动该指针,反之则移动另外一个指针,如果相等则均向后移动. 结束条件是,当任意一个数组的指针移到末尾则跳 ...

  3. JS 两个对象数组合并并去重

    JS两个对象数组合并并去重 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  4. 合并两个数组并去重(ES5和ES6两种方式实现)

    合并两个数组并去重(ES5和ES6两种方式实现) ES6实现方式 let arr1 = [1, 1, 2, 3, 6, 9, 5, 5, 4] let arr2 = [1, 2, 5, 4, 9, 7 ...

  5. #leetcode刷题之路4-寻找两个有序数组的中位数

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2.请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)).你可以假设 nums1 和 nums2 不会 ...

  6. leetcode 题解:Merge Sorted Array(两个已排序数组归并)

    题目: Given two sorted integer arrays A and B, merge B into A as one sorted array. Note:You may assume ...

  7. PHP数组合并+与array_merge的区别分析 & 对多个数组合并去重技巧

    PHP中两个数组合并可以使用+或者array_merge,但之间还是有区别的,而且这些区别如果了解不清楚项目中会要命的! 主要区别是两个或者多个数组中如果出现相同键名,键名分为字符串或者数字,需要注意 ...

  8. STM32F207 两路ADC连续转换及GPIO模拟I2C给MT9V024初始化参数

    1.为了更好的方便调试,串口必须要有的,主要打印一些信息,当前时钟.转换后的电压值和I2C读出的数据. 2.通过GPIO 模拟I2C对镁光的MT9V024进行参数初始化.之前用我以前公司SP0A19芯 ...

  9. 两个有序数组的中位数(第k大的数)

    问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回上中位数). 感觉这种题目挺难的,尤其是将算法完全写对.因为当初自己微软面试的时候遇到了,但是没有想出来思路. ...

随机推荐

  1. (转)12款开源JavaScript库

    JavaScipt几乎是所有前端开发人员必会的编程语言,并且,随着各种移动APP的串红,JavaScript还可以用来开发移动应用.除此以外,为了丰富前端/移动开发,有不少开发者推出了各种基于Java ...

  2. Java 反射机制浅析

    Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反 ...

  3. Tera Term——访问linux的ssh工具

    个人感觉他是一款免费的并且比较好用的ssh工具,下载地址: http://logmett.com/index.php?/products/teraterm.html 下载之后一路下一步就可以了.可以选 ...

  4. 【IOS学习基础】OC类的相关

    几天前突然在别人的类的.m文件中看到这么一句代码:@synthesize xxxx = _xxxx; 当时愣是没理解啥意思,过后才缓过神来发现原来是把一些类的基础知识忘记了,虽然不用过多去深究以前的一 ...

  5. 关于 zend studio 中有些php 内置函数没有提示,或是有‘小黄色感叹号’

    解决办法: 1.修改项目 .buildpath 文件 <?xml version="1.0" encoding="UTF-8"?> <buil ...

  6. sshd被攻击的自动防御方法v2

      1.增加了“频繁攻击的封锁时间”,即设置为上次攻击时间的2倍 2.加入了数据库支持,将攻击者相关信息记录入库,如攻击者ip.攻击次数.封锁时间 3.简化了代码   具体实现步骤如下:   1.创建 ...

  7. Gentoo Linux 学习笔记1

         Gentoo Linux是一个基于portage进行包管理的Linux发行版,最早版本始于2002年.其官方官网为http://www.gentoo.org 目前,Gentoo Linux已 ...

  8. 论山寨手机与Android联姻 【7】 MTK手机软件系统

    MTK feature phone的基本功能是通话和短信,要了解MTK手机软件系统,首先需要简要回顾几个移动网络通讯的基本概念. Figure 38. GSM-GPRS Architecture Co ...

  9. 进程序名得到进程ID和句柄与进程的公司名(使用快照和GetPeFileCompany和VerQueryValueW等函数)

    WORD  GetProcessIdByName(WCHAR *processName){ DWORD processId = 0;HANDLE hProcessSnap=CreateToolhelp ...

  10. 设置windows窗口半透明(使用SetLayeredWindowAttributes API函数)

    所需函数原型:BOOL WINAPI SetLayeredWindowAttributes(HWND hWnd,  COLORREFcrKey,  BYTE bAlpha,  DWORD flag); ...