I have a collection of items in random each having the following data structures:
// NOTE: Was "Vertex" in the comments...
public class Item
{
public string Data { get; set; }
}
public class Node
{
public Item Next { get; set; }
public Item Previous { get; set; }
}
Example:
var a = new Item();
var b = new Item();
var c = new Item();
var d = new Item();
var nodeA = new Node() { Previous = null };
var nodeB = new Node() { Previous = a };
nodeA.Next = b;
var nodeC = new Node() { Previous = b };
nodeB.Next = c;
var nodeD = new Node() { Previous = c, Next = null };
nodeC.Next = d;
// This would be input to the sort method (completely random order).
var items = new []{ nodeC, nodeA, nodeD, nodeB };
// Execute sort
// Result: nodeA, nodeB, nodeC, nodeD.
Obviously a O(n2) solution is possible. However, I would like to sort these in the correct order in less than O(n2). Is this possible?
Looking at it… assuming you aren’t using circular lists, couldn’t you just iterate through your random-order array until you find the starting node (the one with
.Previous == null) and then return the node? I mean, one of the advantages of a linked list is that you don’t have to store references to all the nodes in a separate data structure, just have them each connected to each other. (Well, depending on how the language implementation you’re using does reference counting and garbage collection, if it does them at all.)But basically, unless you have an immediate need after the operation to access an element a certain distance from the starting node, I’d recommend just immediately returning the starting node when encountered and then lazily assigning to an array of the proper size as you use each successive node. In fact, even if you create a new array and assign to it, wouldn’t the worst-time case still just be O(n), with n being the number of nodes? O(n) to find the starting node, and then another O(n) n to iterate through the list, assigning each node to the corresponding index in an array of the same size as your input array.
Based on your updated question, it might be a good idea for you to implement a temporary set of linked lists. As you initially iterate through the list, you’d check the
NextandPreviouselements of each node, and then store theNexts andPreviouses in Dictionary-esque objects (I’m not sure what .NET object would be best suited for that) as keys, with linked-list nodes wrapped around the existingNodes referencing theItems being the values. That way you’d build up the links as you go along without any actual sorting, and would ultimately just iterate through your temporary list, assigning theNodes wrapped by the listnodes to a new array to return.This should be better than O(n^2) due to dictionary accesses generally being constant-time on average (though worst-case asymptotic behavior is still O(n)), I believe.