C#两路list数组归并去重

个相同类型已排序数据进行合并,虽然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

 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4
5 namespace Examples.Utils
6 {
7 public static class CollectionUtils
8 {
9 public static IList<T> MergeSortedLists<T>(Comparison<T> comparision, IList<T> list1, IList<T> list2)
10 {
11 var mergedList = new List<T>(list1.Count + list2.Count);
12 int i = 0, j = 0;
13 while (i < list1.Count && j < list2.Count)
14 {
15 var result = comparision(list1[i], list2[j]);
16 if (result <= 0)
17 {
18 if (result == 0)
19 {
20 j++;
21 }
22 mergedList.Add(list1[i++]);
23 }
24 else
25 {
26 mergedList.Add(list2[j++]);
27 }
28 }
29 while (i < list1.Count)
30 {
31 mergedList.Add(list1[i++]);
32 }
33 while (j < list2.Count)
34 {
35 mergedList.Add(list2[j++]);
36 }
37 return mergedList;
38 }
39 }
40 }

TestExamples

 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using NUnit.Framework;
5
6 namespace Examples.Utils.Tests
7 {
8 [TestFixture]
9 public class CollectionUtilsTests
10 {
11 [Test]
12 public void Merge2TestNoDuplicate()
13 {
14 var list1 = new List<int> {100, 50, 20, 10, 1};
15 var list2 = new List<int> {500, 70, 30, 15, 5};
16 var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
17 var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
18 Assert.AreEqual(expectedList.Count, mergedList.Count);
19 CollectionAssert.AreEqual(expectedList, mergedList);
20 }
21
22 [Test]
23 public void Merge2TestWithDuplicates()
24 {
25 var list1 = new List<int> {100, 50, 20, 10, 1};
26 var list2 = new List<int> {500, 70, 50, 15, 1};
27 var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
28 var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
29 Assert.AreEqual(expectedList.Count, mergedList.Count);
30 CollectionAssert.AreEqual(expectedList, mergedList);
31 }
32
33 [Test]
34 public void Merge2TestNoOverlap1()
35 {
36 var list1 = new List<int> {500, 300, 250, 150, 120};
37 var list2 = new List<int> {100, 50, 20, 10, 1};
38 var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
39 var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
40 Assert.AreEqual(expectedList.Count, mergedList.Count);
41 CollectionAssert.AreEqual(expectedList, mergedList);
42 }
43
44 [Test]
45 public void Merge2TestNoOverlap2()
46 {
47 var list1 = new List<int> {100, 50, 20, 10, 1};
48 var list2 = new List<int> {500, 300, 250, 150, 120};
49 var mergedList = CollectionUtils.MergeSortedLists(IntegerComparision, list1, list2);
50 var expectedList = GetExpectedMergedList(IntegerComparision, list1, list2);
51 Assert.AreEqual(expectedList.Count, mergedList.Count);
52 CollectionAssert.AreEqual(expectedList, mergedList);
53 }
54
55 private static IList<T> GetExpectedMergedList<T>(Comparison<T> comparision, params IList<T>[] lists)
56 {
57 var set = new SortedSet<T>(new ComparisionComparer<T>(comparision));
58 foreach (var list in lists)
59 {
60 foreach (var item in list)
61 {
62 if (!set.Contains(item))
63 {
64 set.Add(item);
65 }
66 }
67 }
68 return set.ToList();
69 }
70
71 private static int IntegerComparision(int x, int y)
72 {
73 return y - x;
74 }
75
76 private class ComparisionComparer<T> : IComparer<T>
77 {
78 private readonly Comparison<T> _comparision;
79
80 public ComparisionComparer(Comparison<T> comparision)
81 {
82 _comparision = comparision;
83 }
84
85 public int Compare(T x, T y)
86 {
87 return _comparision(x, y);
88 }
89 }
90 }
91 }

list数组归并去重的更多相关文章

  1. C#两路list数组归并去重

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

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

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

  3. JS中数组对象去重

    JS数组去重 JS中对数组去重最好不要用unique方法,该方法主要是对dom节点数组的去重,如果对普通的数组元素去重只会去掉与之相邻的重复元素,也就是如果数组中还有不相邻的重复元素存在,将不会被去掉 ...

  4. PHP合并数组及去重

    本文介绍的是一维数组的去重 合并数组的方法 array_merge: 数字键,直接往后添加,key重置 字符串键,后面的数组的值会替代前面的值 +: 数字键,后面的数组的值不会替代前面的值 字符串键, ...

  5. 总结Javascript中数组各种去重的方法

    相信大家都知道网上关于Javascript中数组去重的方法很多,这篇文章给大家总结Javascript中数组各种去重的方法,相信本文对大家学习和使用Javascript具有一定的参考借鉴价值,有需要的 ...

  6. [JAVA]JAVA章1 数组数据去重

    一 利用HashSet进行去重 //定义一个数组:有几个重复项 int[] testarray = {1,2,33,4,2,3,44,5,222,3}; //利用HashSet对数组数据去重 Set& ...

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

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

  8. python之数组元素去重

    参考:如何消除一个数组里面的重复元素?(面试题目) 思路,即创建一个新数组,把原数组中的元素逐个添加到新数组中(判断新数组中是否已经包含原数组中的元素,如果没有,把原数组中的元素添加到新数组,如果已经 ...

  9. JS实现对数组的去重

    JS实现对数组的去重 $scope.validateContect = function(text) { var arr = text; // 若传入的数据为string类型,用逗号分隔 if((ty ...

随机推荐

  1. 108.sqllite3(C语言数据库库)详解

    //创建数据库,插入表,生效 //创建数据库,插入表,生效 void create_database() { //数据库指针 sqlite3 *db=; //打开数据数据库,初始化指针 int res ...

  2. sass工具、相关插件

    http://koala-app.com/index-zh.html 下载koala 把css文件夹(包含.scss后缀的文件)整个拖进去: 然后在sublime打开.scss文件编译,自动生成css ...

  3. spring 通过编程来获取属性文件

    配置可以读取属性: <beans profile="dev"> <context:property-placeholder ignore-resource-not ...

  4. 全然用linux工作,放弃windows

    按: 虽然我们已经不习惯看长篇大论, 但我还是要说, 这是一篇值得你从头读到尾的长篇文章. 2005年9月22日,清华在读博士生王垠在水木社区BLOG上发表了<清华梦的粉碎--写给清华大学的退学 ...

  5. 并发,two

    引言 为了更加形象的描述并发的基础知识,因此本文LZ采用了园子里一度大火的标题形式--"没听说过XXXX,就不要说你XXXX了".希望能够给猿友们一个醒目的警醒,借此来普及并发的基 ...

  6. SN74HC573ANSR 锁存器

    这是它的工作电压范围 这个是功能表,数电上曾经学过: 内部的框图,也是数电的知识:

  7. 【转】CentOS/RHEL/OracleLinux使用UDEV配置ASMDISK

    转自:http://blog.csdn.net/staricqxyz/article/details/8332566 RHEL 5 / CentOS 5 / Oracle Linux 5 [root@ ...

  8. python3 打印九九乘法表

    打印九九乘法表 # !/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan for i in range(1, 10): fo ...

  9. AS2.0鼠标尾随和拖动代码

    1,鼠标尾随. a: Mouse.hide();//隐藏鼠标.Mouse.show()显示鼠标. MC1.startDrag(true);//直接利用函数实现. b: Mouse.hide(); on ...

  10. JSF教程(11)——生命周期之Invoke Application Phase

    在这个阶段JSF实现将处理不论什么应用界别的事件,比如表单的提交或者链接点击后跳转到还有一个页面. 这时假设应用须要重定向不同 的web应用字眼或者产生一个资源其并不喊不论什么的JSF组件,那么就调用 ...