【问题标题】:Sort objects using predefined list of sorted values使用预定义的排序值列表对对象进行排序
【发布时间】:2009-03-16 22:12:20
【问题描述】:

我想知道以与不同数组相同的顺序对对象数组进行排序的最快方法是什么。

这是一个 C# 示例:

class MyClass
{
    public MyClass(int value)
    {
        this.value = value;
    }
    int value;
    public int Value
    {
        get { return value; }
        set { this.value = value; }
    }
}


    static List<int> sortedValuesList;
    static List<MyClass> objectList;

以与 sortedValuesList 相同的顺序对 objectList 进行排序的最快方法是什么? 可能有多个具有相同值的对象。

我已经有简单的算法可以做到,但它是 O(n^2) 并且需要额外的内存。

编辑: 我想目前还不清楚我要做什么。 假设用户在屏幕上看到销售人员的数据网格。他可以按他想要的任何列对它们进行排序。现在用户点击一个按钮,就会显示一个客户表。每个客户都会引用其中一位销售人员。我想根据之前数据网格中销售人员的顺序对客户列表进行排序。

这只是一个理论问题,因为我不需要更高的性能。我只是想知道当您需要使用查找表来比较对象时是否有一些不错的排序算法。

【问题讨论】:

    标签: algorithm sorting


    【解决方案1】:

    把它分成几个步骤:

    1. 遍历您的 sortedValuesList 并从值 -> 索引位置构建地图;这是 O(n log n)
    2. 遍历您的对象并在临时字段中添加索引(同样,O(n log n))
    3. 按临时字段对列表进行排序(也是 O(n log n))

    总算法,O(n log n)。

    或者,如果您不希望有暂存字段,则可以每次通过映射查找排序键,以获得总体 O(n (log n)^2)

    【讨论】:

      【解决方案2】:

      这是我非常简单的解决方案:

      class Program
      {
          static List<int> sortedValuesList;
          static List<MyClass> objectList;
      
          static void Main(string[] args)
          {
              //Generate some test data;
              Random random = new Random();
              objectList = new List<MyClass>();
              sortedValuesList = new List<int>();
              for (int i = 0; i < 10; i++) {
                  MyClass a = new MyClass(random.Next() % 20);
                  objectList.Add(a);
                  if (!sortedValuesList.Contains(a.Value))
                      sortedValuesList.Add(a.Value);
              }
      
              //Shuffle id's
              for (int i = sortedValuesList.Count - 1; i > 0; i--) {
                  int n = random.Next(i + 1);
                  int tempId = sortedValuesList[n];
                  sortedValuesList[n] = sortedValuesList[i];
                  sortedValuesList[i] = tempId;
              }
      
              Console.WriteLine("Reference list:");
              for (int i = 0; i < sortedValuesList.Count; i++) {
                  Console.WriteLine(string.Format("{0,2} {1,5}", i, sortedValuesList[i]));
              }
      
              Console.WriteLine("unsorted list:");
              for (int i = 0; i < objectList.Count; i++) {
                  Console.WriteLine(string.Format("{0,2} {1,5}", i, objectList[i].Value));
              }
      
              //Sort
              List<MyClass> sortedList = new List<MyClass>();
              foreach (int id in sortedValuesList) {
                  sortedList.AddRange(
                      objectList.FindAll(delegate(MyClass a) { return a.Value == id; })
                  );
              }
      
              Console.WriteLine("After sorting:");
              for (int i = 0; i < sortedList.Count; i++) {
                  Console.WriteLine(string.Format("{0,2} {1,5}", i,  sortedList[i].Value));
              }
              Console.ReadKey();
      
          }
      }
      

      【讨论】:

        【解决方案3】:

        首先,帮自己一个忙,使用 List 的通用版本,所以将你的 objectList 定义为

        static List<MyClass> objectList;
        

        但是,在任何一种情况下,由于 List 是对实际对象的引用的集合,而且您似乎希望这两个列表具有相同的顺序,为什么不将一个列表分配给另一个呢?我错过了什么?

        【讨论】:

        • 排序列表不包含实际对象。它只包含用于排序的值。
        【解决方案4】:

        听起来你想要一张地图:

        static Dictionary<int, MyClass> sortedObjectList
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-21
          • 1970-01-01
          相关资源
          最近更新 更多