使用 c# 对自定义链接列表进行排序

Posted

技术标签:

【中文标题】使用 c# 对自定义链接列表进行排序【英文标题】:Sort on a custom Linked List using c# 【发布时间】:2022-01-10 00:11:04 【问题描述】:

我创建了一个自定义链接列表,代码如下。 现在尝试实现一种排序(它是我告诉要做的,不是我所知道的最佳选择),我们如何以最佳可能的时间复杂度或最佳方法来做

我的自定义链表 我的疑问是最后一个节点,在冒泡排序的每个阶段都应该尝试最后排序然后从第一个节点重新开始,如何处理最后一个节点作为它指向第一个节点的点

    public class CustomCircularList<T> : ICollection<T>, IEnumerable<T>
    

        Node<T> head = null;
        Node<T> tail = null;
        int count = 0;
        readonly IEqualityComparer<T> comparer;

        public int Count  get  return count;  
        public bool IsReadOnly  get  return false;  

        public void Add(T item)
        
            this.AddLast(item);
        
         AddLast...
    

我的 Node 类具有三个属性

public T Value  get; private set; 
public Node<T> Next  get; set; 
public Node<T> Previous  get; set; 

我像这样将 IComparer 添加到我的 T 类并尝试像下面这样工作

 public class Fund: IComparer<Fund>
    
        public string fundname get; set; 
        public int Compare([AllowNull] Fund x, [AllowNull] Fund y)
        
            if (x == null || y == null)
            
                return 0;
            

            return x.fundname.CompareTo(y.fundname);
      

【问题讨论】:

只有一种可能的复杂性和方法,因为您的特定要求是使用一种特定的方法,而该方法本身具有特定的时间复杂度。获得更好的方法和/或更好的时间复杂度的方法是使用不同的方法,这违反了您声明的要求 【参考方案1】:

首先,让我假设Node&lt;T&gt; 对象具有(至少)2 个标准属性:ValueNext

public class Node<T> 
  ...
  public T Value get; set;
  public Node<T> Next get; 

既然你有循环链表,

tail.Next == head

我们可以枚举所有除了最后一项

for (Node<T> node = head; !ReferenceEquals(node.Next, head); node = node.Next) 
  ...

仅供参考,如果我们有一个链表(非循环),循环将是(我们要做的就是将head更改为null):

for (Node<T> node = head; !ReferenceEquals(node.Next, null); node = node.Next) 
  ...

代码可以

public void BubbleSort(IComparer<T> comparer = null) 
  comparer ??= Comparer<T>.Default;

  if (comparer is null)
    throw new ArgumentNullException(nameof(comparer));

  if (head is null)
    return; // empty linked list

  bool agenda = true;

  while (agenda) 
    agenda = false;

    for (Node<T> node = head; !ReferenceEquals(node.Next, head); node = node.Next) 
      if (comparer.Compare(node.Value, node.Next.Value) > 0) 
        agenda = true;

        var help = node.Value; 
        node.Value = node.Next.Value;
        node.Next.Value = help;   
       
   

编辑:如果你想对一些自定义类型(T)进行排序,你应该确保T实现IComparable&lt;T&gt;

public class MyClass: IComparable<MyClass> 
  ...
  public int CompareTo(MyClass other) 
    TODO: return 0 if other == this, -1 if this < other, +1 if this > other
  

或者您应该实现一个比较器 IComparer&lt;MyClass&gt;,您应该将其作为参数提供:

public class MyComparer<MyClass> 
  public int Compare(MyClass x, MyClass y) 
    //TODO: return 0 when x == y, -1 when x < y, when x > y
  

然后

MyCircularLinkedList.BubbleSort(new MyComparer());

【讨论】:

我的节点类 3 属性,T 值,下一个节点和上一个节点,这样你的方法将是相同的 @mainak:我明白了,NextValue 就够了 如何将此冒泡排序用于自定义对象或类 mainak: 如果是自定义类 (T) 如果它没有实现 IComparable&lt;T&gt; 即它没有提供一些默认算法如何比较它的实例,你必须通过 比较器作为参数。 你能给我任何示例链接吗

以上是关于使用 c# 对自定义链接列表进行排序的主要内容,如果未能解决你的问题,请参考以下文章

是否可以根据这些对象的参数对自定义类对象列表进行子集化? (没有 LINQ)

Angular 7对自定义数据源进行排序

如何使用快速编码根据特定的排序顺序对自定义对象进行排序

按属性对自定义对象的 ArrayList 进行排序

使用内部对象的实例变量的值对自定义对象数组进行排序

无法在 Drupal 7 的视图中对自定义字段进行排序或过滤