将 2 个排序的整数列表合并为一个,按升序排列。我的方法太乱了

merging 2 sorted integer list into one ,in ascending order. my method is getting too messy

static List<int>Merge(List<int> list_a, List<int> list_b)
{
    List<int> list_c=new List<int>();
    
    int countA = 0, countB = 0;

        for (int i =0;i< list_a.Count + list_b.Count-2;i++)
        {
            if (list_a[countA]<=list_b[countB])
            {
                list_c.Add(list_a[countA]);
                countA ++;
            }
            else
            {
                list_c.Add(list_b[countB]);
                countB ++;
            }
        }
        return list_c;
    }

我的想法是通过 for 循环的次数与最后 list_c 元素的数量一样多 比较两个列表中的每个元素,然后添加 list_c 中的最小元素 我已经有办法检查两个列表是否按升序排列 当我用

测试它时
List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
List<int> myList2 = new List<int> { 4, 5, 6};
Console.WriteLine("new list :{ " + string.Join(",", Merge(myList1, myList2)));

countB 一旦添加了列表 b 中的最后一个元素,就会越界,该 for 循环中的下一个比较将无效,因为它比较 list_b[3]

考虑到您要使用循环:

public static List<int> Merge(List<int> list_a, List<int> list_b)
{
    int firstListIndexer = 0, secondListIndexer = 0;    
    List<int> list_c = new List<int>();

    // Traverse lists, until one of them run out of the elements
    while (firstListIndexer < list_a.Count && secondListIndexer < list_b.Count)
    {
        
        if (list_a[firstListIndexer] < list_b[secondListIndexer])
            list_c.Add(list_a[firstListIndexer++]);
        else
            list_c.Add(list_b[secondListIndexer++]);
    }
 
    // Store remaining elements of first list
    while (firstListIndexer < list_a.Count)
        list_c.Add(list_a[firstListIndexer++]);
 
    // Store remaining elements of second list
    while (secondListIndexer < list_b.Count)
        list_c.Add(list_b[secondListIndexer++]);
    return list_c;
}

此外,您还可以阅读 this 以提高您对该主题的了解。

您在较短数组上的索引超出了其最大索引。需要检查Count是否超过最大索引。

class Program {
  static List<int> Merge(List<int> list_a, List<int> list_b) {
    List<int> list_c = new List<int>();

    int countA = 0, countB = 0;

    for (int i = 0; i < list_a.Count + list_b.Count; i++) {
      if (countA < list_a.Count && countB < list_b.Count) {
        if (list_a[countA] <= list_b[countB]) {
          list_c.Add(list_a[countA]);
          countA++;
        }
        else {
          list_c.Add(list_b[countB]);
          countB++;
        }
      }
      else if (countA < list_a.Count) {
        list_c.Add(list_a[countA]);
        countA++;
      }
      else {
        list_c.Add(list_b[countB]);
        countB++;
      }

    }
    return list_c;
  }
  static void Main(string[] args) {
    List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
    List<int> myList2 = new List<int> { 4, 5, 6 };
    Console.WriteLine("new list :{ " + string.Join(",", Merge(myList1, myList2)) + "}");
  }
}

如果我们可以假设两个列表都是按升序排列的,那么您可以像这样合并集合以遵守升序。

static List<int> MergeTowAscendinglyOrderedCollections(IEnumerable<int> collectionA, IEnumerable<int> collectionB)
{
    var result = new List<int>();
    IEnumerator<int> iteratorA = collectionA.GetEnumerator();
    IEnumerator<int> iteratorB = collectionB.GetEnumerator();

    bool doesIteratorAHaveRemainingItem = iteratorA.MoveNext();
    bool doesIteratorBHaveRemainingItem = iteratorB.MoveNext();

    void SaveIteratorAsCurrentAndAdvanceIt()
    {
        result.Add(iteratorA.Current);
        doesIteratorAHaveRemainingItem = iteratorA.MoveNext();
    }

    void SaveIteratorBsCurrentAndAdvanceIt()
    {
        result.Add(iteratorB.Current);
        doesIteratorBHaveRemainingItem = iteratorB.MoveNext();
    }

    do
    {
        if (iteratorA.Current < iteratorB.Current)
        {
            if (doesIteratorAHaveRemainingItem) SaveIteratorAsCurrentAndAdvanceIt(); 
            else SaveIteratorBsCurrentAndAdvanceIt();
        }
        else if (iteratorA.Current > iteratorB.Current)
        {
            if (doesIteratorBHaveRemainingItem) SaveIteratorBsCurrentAndAdvanceIt(); 
            else SaveIteratorAsCurrentAndAdvanceIt();
        }
        else if (iteratorA.Current == iteratorB.Current)
        {
            SaveIteratorAsCurrentAndAdvanceIt();
            SaveIteratorBsCurrentAndAdvanceIt();
        }

    } while (doesIteratorAHaveRemainingItem || doesIteratorBHaveRemainingItem);

    return result;
}

为了防止重复,我已将两个数字都添加到合并列表中,但根据您的业务需求,您可以调整代码以从结果中省略一个或两个值。

你可以做一个联盟

List<int> myList1 = new List<int> { 1, 2, 3, 7, 8, 9 };
List<int> myList2 = new List<int> { 4, 5, 6};

var merged = myList1.Union(myList2).OrderBy(o=>o).ToList();

foreach(int number in merged)
Console.WriteLine(number);

输出如下

1 2个 3个 4个 5个 6个 7 8个 9

如果你必须实现你的 serlf:

使用协程在短短几行中实现没有计数器和索引:

      class Program {
    
        static void Main() {

          List<int> l1 = new List<int>() { 9,8, 7, 5, 3, 1 };
          List<int> l2 = new List<int>() {12 ,10, 8, 6, 4, 2 };
          IEnumerable<int> res = MergeAscending(sl1, sl2);

          foreach (int item in res) {
            Console.Write($"{item},");
          }

          Console.Read();
        }
    
        static IEnumerable<T> MergeAscending<T>(IEnumerable<T> l1, IEnumerable<T> l2) where T : struct, IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable {
    
           IEnumerator<T> e1 = l1.AsParallel().OrderBy(e => e).GetEnumerator();
           IEnumerator<T> e2 = l2.AsParallel().OrderBy(e => e).GetEnumerator();

           IEnumerator<T> longest; //to yield longest list remains

//First move needed to init first "Current"
          e1.MoveNext();
          e2.MoveNext();
    
//yields smaller current value and move its IEnumerable pointer
//breaks while loop if no more values in some Enumerable and mark the other one as longest

          while (true) {
            if (e1.Current.CompareTo(e2.Current) < 0) {
              yield return e1.Current;
              if (!e1.MoveNext()) { longest = e2; break; }
            }
            else {
              yield return e2.Current;
              if (!e2.MoveNext()) { longest = e1; break; }
            }
          }

    //finish the longest Enumerator
          do {
            yield return longest.Current;
          } while (longest.MoveNext());
    
        }
      }

不管怎样,我的推荐和Siavash在评论中的一样:

var merged = myList1.Union(myList2).AsParallel().OrderBy(e => e).ToList();