McDonut
McDonut

Reputation: 1

How to compare objects of a nested class C#

I'm trying to implement a generic binary min heap. I have a minHeap class which represents the heap, and a nested Node class which represents nodes. So minHeap consists of Node objects. Node class has two attributes: some generic data and an integer key. The problem is, I cannot for the life of me figure out how to compare two objects of Node type. I've tried implementing Icomparable on Node, overloading operators: I can't get it to work. Here is the basic structure so far (I've removed the unimportant bits):

'''

public class MinHeap<T>
{

    static private int INITIAL_CAPACITY = 10;
    private Node[] heap = new Node[INITIAL_CAPACITY];

    private int heapSize = 0;
    private int heapCapacity = INITIAL_CAPACITY;

    private class Node
    {
        private T data;
        private int key;
    }
    ...

'''

What I want to do is overload operators such as <, >, == to be able to compare Nodes in the minHeap class' methods. For example, when I insert a new Node into the minHeap, I need to compare the new Node's key to the another Node's key. How could I achieve this?

Upvotes: 0

Views: 430

Answers (1)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186813

Alas, it's impossible now to implement a simgle <=> operator and have all the >, <, == etc. operators as well as IComparable<Node>, IEquatable<Node> ... We have to write a lot of bolierplate code.

I suggest implementing

  public static int Compare(Node left, Node right)

method which compares two Node instances and then you can easily design all the rest oneliners:

  private class Node : IComparable<Node>, IEquatable<Node> {
    private T data;
    private int key;

    public static int Compare(Node left, Node right) {
      if (ReferenceEquals(left, right)) // we can't use == here
        return 0;
      if (left is null) // or ReferenceEquals(left, null) to avoid ==
        return -1;
      if (right is null)
        return 1;

      //TODO: return compare result
      //        negative if left < right, 
      //               0 if left == right 
      //        positive if left > right 
      return left.key.CompareTo(right.key);
    }

    //TODO: Check: I've assumed that comparison is key based
    public override int GetHashCode() => key;

    // A lot of boiler plate code below...
    public int CompareTo(Node other) => Compare(this, other);
    public bool Equals(Node other) => Compare(this, other) == 0;
    public override bool Equals(object obj) => obj is Node node && Equals(node);

    public static bool operator ==(Node left, Node right) => Compare(left, right) == 0;
    public static bool operator !=(Node left, Node right) => Compare(left, right) != 0;
    public static bool operator >=(Node left, Node right) => Compare(left, right) >= 0;
    public static bool operator > (Node left, Node right) => Compare(left, right) > 0;
    public static bool operator < (Node left, Node right) => Compare(left, right) < 0;
    public static bool operator <=(Node left, Node right) => Compare(left, right) <= 0;
  }

Upvotes: 2

Related Questions