Advertisement
logxx

Balance

Mar 13th, 2022 (edited)
902
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.91 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3.  
  4. namespace ConsoleAppCS
  5. {
  6.     class Program
  7.     {
  8.         static void Main(string[] args)
  9.         {
  10.             BinTree tree = new BinTree();
  11.             using (StreamReader sr = new StreamReader("input.txt"))
  12.             {
  13.                 string[] toks = sr.ReadLine().Split();
  14.                 foreach (string s in toks)
  15.                     tree.Add(int.Parse(s));
  16.             }
  17.             Console.WriteLine("tree.IsBalanced(): {0}", tree.IsBalanced());
  18.             Tuple<object, object> res =  tree.CanBeBalanced();
  19.             if (res == null)
  20.                 Console.WriteLine("Can't balance the tree...");
  21.             else if (res.Item1 == null)
  22.                 Console.WriteLine("Tree is already balanced!");
  23.             else
  24.             {
  25.                 Console.WriteLine("Tree can be balanced with element from {0} to {1}", res.Item1, res.Item2);
  26.                 Console.WriteLine("Adding {0}", res.Item1);
  27.                 tree.Add(res.Item1);
  28.                 Console.WriteLine("tree.IsBalanced(): {0}", tree.IsBalanced());
  29.             }
  30.         }
  31.     }
  32. }
  33.  
  34.  
  35.  
  36.  
  37. using System;
  38.  
  39. namespace ConsoleAppCS
  40. {
  41.     internal class BinTree
  42.     {
  43.         class Node
  44.         {
  45.             public object value;
  46.             public Node leftChild, rightChild;
  47.             public int Counter { get; private set; }
  48.             public Node(object value)
  49.             {
  50.                 this.value = value;
  51.                 leftChild = rightChild = null;
  52.                 Counter = 1;
  53.             }
  54.  
  55.             public static void Add(ref Node r, object value)
  56.             {
  57.                 if (r == null)
  58.                     r = new Node(value);
  59.                 else
  60.                 {
  61.                     ++r.Counter;
  62.                     if (((IComparable)value).CompareTo(r.value) < 0)
  63.                         Add(ref r.leftChild, value);
  64.                     else
  65.                         Add(ref r.rightChild, value);
  66.                 }
  67.             }
  68.  
  69.             public static void PrintInorder(Node r)
  70.             {
  71.                 if (r != null)
  72.                 {
  73.                     PrintInorder(r.leftChild);
  74.                     Console.Write(r.value + " ");
  75.                     PrintInorder(r.rightChild);
  76.                 }
  77.             }
  78.  
  79.             public static void PrintPreorder(Node r)
  80.             {
  81.                 if (r != null)
  82.                 {
  83.                     Console.Write(r.value + " ");
  84.                     PrintPreorder(r.leftChild);
  85.                     PrintPreorder(r.rightChild);
  86.                 }
  87.             }
  88.  
  89.             public static void PrintPostorder(Node r)
  90.             {
  91.                 if (r != null)
  92.                 {
  93.                     PrintPostorder(r.leftChild);
  94.                     PrintPostorder(r.rightChild);
  95.                     Console.Write(r.value + " ");
  96.                 }
  97.             }
  98.  
  99.             public static Node Search(Node r, object value)
  100.             {
  101.                 if (r == null)
  102.                     return null;
  103.                 int cmpRes = ((IComparable)r.value).CompareTo(value);
  104.                 if (cmpRes == 0)
  105.                     return r;
  106.                 else if (cmpRes > 0)
  107.                     return Search(r.leftChild, value);
  108.                 else return Search(r.rightChild, value);
  109.             }
  110.  
  111.             public static bool Delete(ref Node r, object key)
  112.             {
  113.                 if (r == null)
  114.                     return false;
  115.                 int cmpRes = ((IComparable)r.value).CompareTo(key);
  116.                 if (cmpRes > 0)
  117.                     if (Delete(ref r.leftChild, key))
  118.                     {
  119.                         --r.Counter;
  120.                         return true;
  121.                     }
  122.                     else return false;
  123.                 else if (cmpRes < 0)
  124.                     if (Delete(ref r.rightChild, key))
  125.                     {
  126.                         --r.Counter;
  127.                         return true;
  128.                     }
  129.                     else return false;
  130.                 else if (r.leftChild == null)
  131.                     r = r.rightChild;
  132.                 else if (r.rightChild == null)
  133.                     r = r.leftChild;
  134.                 else Del(r, ref r.leftChild);
  135.  
  136.                 return true;
  137.             }
  138.  
  139.             private static void Del(Node r, ref Node l)
  140.             {
  141.                 if (l.rightChild != null)
  142.                     Del(r, ref l.rightChild);
  143.                 else
  144.                 {
  145.                     r.value = l.value;
  146.                     l = l.leftChild;
  147.                 }
  148.             }
  149.  
  150.             public static bool CanBeBalanced(ref Node r, ref object min, ref object max, ref bool needsTo)
  151.             {
  152.                 if (r == null)
  153.                     return true;
  154.  
  155.                 int lc = r.leftChild != null ? r.leftChild.Counter : 0;
  156.                 int rc = r.rightChild != null ? r.rightChild.Counter : 0;
  157.                 int diff = lc - rc;
  158.  
  159.                 if (Math.Abs(diff) > 2)
  160.                     return false;
  161.  
  162.                 if (Math.Abs(diff) == 2)
  163.                     needsTo = true;
  164.  
  165.                 if (diff > 0)
  166.                 {
  167.                     min = r.value;
  168.                     return CanBeBalanced(ref r.rightChild, ref min, ref max, ref needsTo) && IsBalanced(r.leftChild);
  169.                 }
  170.                 else if (diff < 0)
  171.                 {
  172.                     max = (int)r.value - 1;
  173.                     return CanBeBalanced(ref r.leftChild, ref min, ref max, ref needsTo) && IsBalanced(r.rightChild);
  174.                 }
  175.                 else
  176.                 {
  177.                     object tempMin = r.value, tempMax = max;
  178.                     bool tmpNeeds = needsTo;
  179.                     if (CanBeBalanced(ref r.rightChild, ref tempMin, ref tempMax, ref tmpNeeds) && IsBalanced(r.leftChild))
  180.                     {
  181.                         min = tempMin;
  182.                         max = tempMax;
  183.                         needsTo = tmpNeeds;
  184.                         return true;
  185.                     }
  186.                     max = (int)r.value - 1;
  187.                     return CanBeBalanced(ref r.leftChild, ref min, ref max, ref needsTo) && IsBalanced(r.rightChild);
  188.                 }
  189.             }
  190.  
  191.             public static bool IsBalanced(Node r)
  192.             {
  193.                 if (r == null)
  194.                     return true;
  195.  
  196.                 int lc = r.leftChild == null ? 0 : r.leftChild.Counter;
  197.                 int rc = r.rightChild == null ? 0 : r.rightChild.Counter;
  198.                 int diff = Math.Abs(lc - rc);
  199.  
  200.                 return diff <= 1 && IsBalanced(r.leftChild) && IsBalanced(r.rightChild);
  201.             }
  202.         }
  203.  
  204.         Node root;
  205.         object minElem, maxElem;
  206.  
  207.         public BinTree()
  208.         {
  209.             root = null;
  210.         }
  211.  
  212.         private BinTree(Node root)
  213.         {
  214.             this.root = root;
  215.         }
  216.  
  217.         public void Add(object value)
  218.         {
  219.             if (minElem == null || ((IComparable)value).CompareTo(minElem) < 0)
  220.                 minElem = value;
  221.             if (maxElem == null || ((IComparable)value).CompareTo(maxElem) > 0)
  222.                 maxElem = value;
  223.             Node.Add(ref root, value);
  224.         }
  225.  
  226.         public void PrintInorder()
  227.         {
  228.             Node.PrintInorder(root);
  229.             Console.WriteLine();
  230.         }
  231.  
  232.         public void PrintPreorder()
  233.         {
  234.             Node.PrintPreorder(root);
  235.             Console.WriteLine();
  236.         }
  237.  
  238.         public void PrintPostorder()
  239.         {
  240.             Node.PrintPostorder(root);
  241.             Console.WriteLine();
  242.         }
  243.  
  244.         public BinTree Search(object value)
  245.         {
  246.             return new BinTree(Node.Search(root, value));
  247.         }
  248.  
  249.         public void Delete(object key)
  250.         {
  251.             Node.Delete(ref root, key);
  252.             if (key == minElem)
  253.             {
  254.                 Node el = root;
  255.                 while (el.leftChild != null)
  256.                     el = el.leftChild;
  257.                 minElem = el.leftChild.value;
  258.             }
  259.             if (key == maxElem)
  260.             {
  261.                 Node el = root;
  262.                 while (el.rightChild != null)
  263.                     el = el.rightChild;
  264.                 maxElem = el.rightChild.value;
  265.             }
  266.         }
  267.  
  268.         public bool IsBalanced()
  269.         {
  270.             return Node.IsBalanced(root);
  271.         }
  272.  
  273.         public Tuple<object, object> CanBeBalanced()
  274.         {
  275.             object min = (int)minElem - 1, max = (int)maxElem + 1;
  276.             bool needs = false;
  277.             bool res = Node.CanBeBalanced(ref root, ref min, ref max, ref needs);
  278.  
  279.             if (res)
  280.             {
  281.                 if (needs)
  282.                     return new Tuple<object, object>(min, max);
  283.                 else
  284.                     return new Tuple<object, object>(null, null);
  285.             }
  286.             return null;
  287.         }
  288.     }
  289. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement