繁体   English   中英

合并两个已经在C#中排序的列表

[英]Merging two lists which are already sorted in c#

所以我有两个带有可交付成果的排序列表,我想将它们合并。 我以前从未进行过此操作,也无法使其真正起作用。 您可以在下面看到我写的方法。 我无法弄清楚while语句,因为它始终会触发异常。 我不知道该怎么办...

public void MergeLists(List<Deliverable> a, List<Deliverable> b)
{
    int index1 = 0;
    int index2 = 0;

    while (a.Count() >= index1 || b.Count() >= index2)
    {
        if (a[index1].ID> b[index2].ID)
        {
            FinalDeliverables.Add(a[index1]);
            index1++;
        }
        else if (a[index1].ID < b[index2].ID)
        {
            FinalDeliverables.Add(a[index2]);
            index2++;
        }
        else if (a[index1].ID == b[index2].ID)
        {
            FinalDeliverables.Add(a[index1]);
            FinalDeliverables.Add(a[index2]);
            index1++;
            index2++;
        }
    }
}

我相信,您得到的异常来自空指针。 例如,如果您已经到达列表之一的末尾,但是while循环仍在尝试比较值,则会发生这种情况。 一种解决方法是,简单地在if语句之前添加一个检查,以查看是否已到达列表末尾中的一个(或两个)。 如果是这样,则只需添加其他列表中的其余项即可。

public void MergeLists(List<Deliverable> a, List<Deliverable> b)
{
    int index1 = 0;
    int index2 = 0;

    while (true)
    {
        // if the end of the 'a' list has been reached, then add
        // everything from the 'b' list and break from the loop
        if (index1 >= a.Count()) {
            for (int i=index2; i < b.Count(); ++i) {
                FinalDeliverables.Add(b[i]);
            }
            break;
        }

        // if the end of the 'b' list has been reached, then add
        // everything from the 'a' list and break from the loop
        if (index2 >= b.Count()) {
            for (int i=index1; i < a.Count(); ++i) {
                FinalDeliverables.Add(a[i]);
            }
            break;
        }
        if (a[index1].ID > b[index2].ID)
        {
            FinalDeliverables.Add(a[index1]);
            index1++;
        }
        else if (a[index1].ID < b[index2].ID)
        {
            FinalDeliverables.Add(a[index2]);
            index2++;
        }
        else if (a[index1].ID == b[index2].ID)
        {
            FinalDeliverables.Add(a[index1]);
            FinalDeliverables.Add(a[index2]);

            index1++;
            index2++;
        }
    }
}

请注意,此重构的副作用是原始的while循环不再需要检查边界。 而是,当列表之一用完时,循环将终止。

另请注意,此解决方案假定您的输入列表按降序排序。

您可以为此使用LINQ扩展方法, MergeLists的方法签名将如下所示:

public void MergeLists(List<Deliverable> a, List<Deliverable> b) 
{
    var finalList = a.Concat(b);
    List<Deliverable> FinalSortedList = finalList.OrderBy(x => x.ID).ToList();
}

否则,您可以像下面这样修改自己的方法:在此之前,让我假设以下内容:输入列表a的元素计数将始终大于b的元素计数。 因此,您需要做的是在调用方法之前也检查元素的数量。 因此,调用将如下所示:

if(a.Count>b.Count)
   MergeLists(a,b);
else
   MergeLists(b,a);

您提到两个输入商品已排序,让我假设这些列表是按升序排序的。 现在考虑以下代码:

public void MergeLists(List<Deliverable> a, List<Deliverable> b)
{
    int largeArrayCount = a.Count;
    int currentBIndex = 0;
    List<Deliverable> FinalResult = new List<Deliverable>();
    for (int i = 0; i < largeArrayCount; i++)
    {
        if (i < b.Count)
        {
            if (a[i].ID >= b[i].ID)
            {
                // Add All elements of B Which is smaller than current element of A
                while (a[i].ID <= b[currentBIndex].ID)
                {
                    FinalResult.Add(b[currentBIndex++]);
                }
            }
            else
            {
                FinalResult.Add(a[i]);
            }
        }
        else
        {
            // No more elements in b so no need for checking
            FinalResult.Add(a[i]);
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM