using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SomewhereIBelong { enum Color { red, black }; class RBNode where T : IComparable { public T key; public Color color; public RBNode left; public RBNode right; public RBNode p;// parent public RBNode() { color = Color.red; left = null; right = null; p = null; key = default(T); } public static bool operator <(RBNode first, RBNode second) { return first.key.CompareTo(second.key) < 0; } public static bool operator >(RBNode first, RBNode second) { return first.key.CompareTo(second.key) > 0; } } class RBTree where T : IComparable { private RBNode _root; public RBTree() { _root = null; } public RBTree(T[] source, int count) : this() { for (int i = 0; i < count; i++) { RBNode node = new RBNode(); node.key = source[i]; Insert(node); } } public void Insert(RBNode node) { RBNode y = null; RBNode x = _root; while (x != null) { y = x; if (x > node) x = x.left; else x = x.right; } node.p = y; if (y == null) { _root = node; } else if (y > node) y.left = node; else y.right = node; node.left = null; node.right = null; node.color = Color.red; RBInsertFixUp(node); } public bool Serach(T key) { return SearchImp(key, _root); } private bool SearchImp(T key, RBNode curnode) { if (curnode.key.CompareTo(key) < 0) { if (curnode.right != null) return SearchImp(key, curnode.right); } else if (curnode.key.CompareTo(key) > 0) { if (curnode.left != null) { return SearchImp(key, curnode.left); } } else { return true; } return false; } private void RBInsertFixUp(RBNode node) { RBNode y; while (node.p.color == Color.red) { if (node.p == node.p.p.left) { y = node.p.p.right; if (y.color == Color.red) { node.p.color = Color.black; y.color = Color.black; node.p.p.color = Color.red; node = node.p.p; continue; } else if (node == node.p.right) { node = node.p; LeftRotate(node); } node.p.color = Color.black; node.p.p.color = Color.red; RightRotate(node.p.p); } else { y = node.p.p.left; if (y.color == Color.red) { node.p.color = Color.black; y.color = Color.black; node.p.p.color = Color.red; node = node.p.p; continue; } else if (node == node.p.left) { node = node.p; RightRotate(node); } node.p.color = Color.black; node.p.p.color = Color.red; LeftRotate(node.p.p); } } _root.color = Color.black; } private void LeftRotate(RBNode x) { RBNode y; y = x.right; x.right = y.left; if (y.left != null) y.left.p = x; y.p = x.p; if (x.p == null) _root = y; else if (x == x.p.left) x.p.left = y; else x.p.right = y; y.left = x; x.p = y; } private void RightRotate(RBNode x) { RBNode y; y = x.left; x.left = y.right; if (y.right != null) y.right.p = x; y.p = x.p; if (x.p == null) _root = y; else if (x == x.p.right) x.p.right = y; else x.p.left = y; y.right = x; x.p = y; } public List BFS() { List keys = new List(); RBNode node = _root; Queue> queue = new Queue>(); queue.Enqueue(_root); while (queue.Count > 0) { RBNode item = queue.Dequeue(); if(item.left!=null) queue.Enqueue(item.left); if(item.right!=null) queue.Enqueue(item.right); keys.Add(item.key); } return keys; } } }