public void CopyInto(T[] vals, int i) { CDLL <T> node = this; do { vals[i++] = node.val; // still, implicit checkcasts at runtime node = node.next; } while (node != this); }
public void PrintFwd() { CDLL <T> node = this; do { Console.WriteLine(node.val); node = node.next; } while (node != this); Console.WriteLine(); }
public int Size() { int count = 0; CDLL <T> node = this; do { count++; node = node.next; } while (node != this); return(count); }
public static Point[] ConvexHull(Point[] pts) { // Sort points lexicographically by increasing (x, y) int N = pts.Length; Polysort.Quicksort <Point>(pts); Point left = pts[0], right = pts[N - 1]; // Partition into lower hull and upper hull CDLL <Point> lower = new CDLL <Point>(left), upper = new CDLL <Point>(left); for (int i = 0; i < N; i++) { double det = Point.Area2(left, right, pts[i]); if (det > 0) { upper = upper.Append(new CDLL <Point>(pts[i])); } else if (det < 0) { lower = lower.Prepend(new CDLL <Point>(pts[i])); } } lower = lower.Prepend(new CDLL <Point>(right)); upper = upper.Append(new CDLL <Point>(right)).Next; // Eliminate points not on the hull eliminate(lower); eliminate(upper); // Eliminate duplicate endpoints if (lower.Prev.val.Equals(upper.val)) { lower.Prev.Delete(); } if (upper.Prev.val.Equals(lower.val)) { upper.Prev.Delete(); } // Join the lower and upper hull Point[] res = new Point[lower.Size() + upper.Size()]; lower.CopyInto(res, 0); upper.CopyInto(res, lower.Size()); return(res); }
// Graham's scan private static void eliminate(CDLL <Point> start) { CDLL <Point> v = start, w = start.Prev; bool fwd = false; while (v.Next != start || !fwd) { if (v.Next == w) { fwd = true; } if (Point.Area2(v.val, v.Next.val, v.Next.Next.val) < 0) // right turn { v = v.Next; } else { // left turn or straight v.Next.Delete(); v = v.Prev; } } }
public CDLL <T> Append(CDLL <T> elt) { elt.prev = this; elt.next = next; next.prev = elt; next = elt; return(elt); }
public CDLL <T> Prepend(CDLL <T> elt) { elt.next = this; elt.prev = prev; prev.next = elt; prev = elt; return(elt); }
// Delete: adjust the remaining elements, make this one point nowhere public void Delete() { next.prev = prev; prev.next = next; next = prev = null; }
// A new CDLL node is a one-element circular list public CDLL(T val) { this.val = val; next = prev = this; }