两个相同类型已排序数据进行合并,虽然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. javascript中的同源策略

    如果两个页面拥有相同的协议(protocol),端口(如果指定),和主机,那么这两个页面就是属于同一个源 览器有一个很重要的概念——同源策略(Same-Origin Policy).所谓同源是指,域名 ...

  2. Emmet 插件使用教程

    1)使用 Emmet 生成 HTML 的语法详解生成 HTML 文档初始结构 HTML 文档的初始结构,就是包括 doctype.html.head.body 以及 meta 等内容.你只需要输入一个 ...

  3. Android 常用 adb 命令总结

    Android 常用 adb 命令总结 针对移动端 Android 的测试, adb 命令是很重要的一个点,必须将常用的 adb 命令熟记于心, 将会为 Android 测试带来很大的方便,其中很多命 ...

  4. Home键屏蔽

    公司要开发一款智能终端,设备中预装了本公司开发的软件,但是为了避免用户进入Android系统的界面,这个时候我们就需要对其中的按键加以屏蔽,尤其是Home键,在普通的情况下,当我们点击Home按键的时 ...

  5. Daily Sentence

    2016-12-05 08:59:15 Knowing yourself is the beginning of all wisdom. 智者始于自知. 2016-05-01 19:38:25 The ...

  6. zendStudio安装Xdebug项目断点调试

    1,首先安装xdebug插件 传送门 2,配置php.ini文件如下: [XDebug] xdebug.profiler_append = xdebug.profiler_enable = xdebu ...

  7. HDU 1027 - Ignatius and the Princess II

    第 m 大的 n 个数全排列 DFS可过 #include <iostream> using namespace std; int n,m; ]; bool flag; ]; void d ...

  8. 用Struts2标签实现Map的迭代

    最近在做一个论坛,论坛通常分为几个主版块,每一个主版块下面又有几个子版块. 想不出更好的展现方式,最终采用了如下的方法来实现: 用一个Map,HashMap或者Treemap承载之.一个子版块名字对应 ...

  9. JavaScript处理HTML DOM

    本来只想好好写一篇博文,最后弄到好像重构一样了,越做越不满意,先这样吧:) HTML DOM - JavaScript处理HTML DOM 获取HTML元素 改变HTML元素 增删HTML元素 添加事 ...

  10. PHP filter例子

    <?phpfunction convertSpace($str) { return str_replace(' ', '_', $str);} $str = 'i am a great guy! ...