using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AllBalancedTrees
{
class Program
{
static void Main(string[] args)
{
char[] nodes = { 'A', 'B', 'C', 'D', 'E' };
AllBalancedTrees<char> AllBalancedTrees = new AllBalancedTrees<char>();
foreach (char[] a in AllBalancedTrees.allBalancedTreeCombinations(nodes))
{
foreach (char c in a)
{
Console.Write(c + " ");
}
Console.WriteLine();
}
Console.ReadKey();
}
}
class AllBalancedTrees<T>
{
public IEnumerable<T[]> allBalancedTreeCombinations(T[] nodes)
{
T[] result;
if (nodes.Length == 1)
{
yield return nodes;
}
else if (nodes.Length == 2)
{
yield return nodes;
T[] nodes2 = new T[2];
nodes2[0] = nodes[1];
nodes2[1] = nodes[0];
yield return nodes2;
}
else if (nodes.Length % 2 == 1)
{
int mid = (nodes.Length - 1) / 2;
T[] left = new T[mid];
T[] right = new T[mid];
Array.Copy(nodes, 0, left, 0, mid);
Array.Copy(nodes, mid + 1, right, 0, mid);
foreach (T[] l in allBalancedTreeCombinations(left))
{
foreach (T[] r in allBalancedTreeCombinations(right))
{
result = new T[nodes.Length];
result[0] = nodes[mid];
foreach (T[] a in allMergeCombinations(l, r))
{
Array.Copy(a, 0, result, 1, a.Length);
yield return result;
}
}
}
}
else
{
int mid = (nodes.Length) / 2;
T[] left = new T[mid];
T[] right = new T[mid - 1];
Array.Copy(nodes, 0, left, 0, mid);
Array.Copy(nodes, mid + 1, right, 0, mid - 1);
foreach (T[] l in allBalancedTreeCombinations(left))
{
foreach (T[] r in allBalancedTreeCombinations(right))
{
result = new T[nodes.Length];
result[0] = nodes[mid];
foreach (T[] a in allMergeCombinations(l, r))
{
Array.Copy(a, 0, result, 1, a.Length);
yield return result;
}
}
}
mid = nodes.Length / 2 - 1;
left = new T[mid];
right = new T[mid + 1];
Array.Copy(nodes, 0, left, 0, mid);
Array.Copy(nodes, mid + 1, right, 0, mid+1);
foreach (T[] l in allBalancedTreeCombinations(left))
{
foreach (T[] r in allBalancedTreeCombinations(right))
{
result = new T[nodes.Length];
result[0] = nodes[mid];
foreach (T[] a in allMergeCombinations(l, r))
{
Array.Copy(a, 0, result, 1, a.Length);
yield return result;
}
}
}
}
}
public IEnumerable<T[]> allMergeCombinations(T[] firstArray, T[] secondArray)
{
if (firstArray.Length == 0)
{
yield return secondArray;
}
else if (secondArray.Length == 0)
{
yield return firstArray;
}
else
{
T[] result;
T[] firstMinusOne;
firstMinusOne = new T[firstArray.Length - 1];
Array.Copy(firstArray, 1, firstMinusOne, 0, firstMinusOne.Length);
foreach (T[] a in allMergeCombinations(firstMinusOne, secondArray))
{
result = new T[firstArray.Length + secondArray.Length];
result[0] = firstArray[0];
Array.Copy(a, 0, result, 1, a.Length);
yield return result;
}
T[] secondMinusOne;
secondMinusOne = new T[secondArray.Length - 1];
Array.Copy(secondArray, 1, secondMinusOne, 0, secondMinusOne.Length);
foreach (T[] a in allMergeCombinations(firstArray, secondMinusOne))
{
result = new T[firstArray.Length + secondArray.Length];
result[0] = secondArray[0];
Array.Copy(a, 0, result, 1, a.Length);
yield return result;
}
}
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLkxpbnE7CnVzaW5nIFN5c3RlbS5UZXh0OwoKbmFtZXNwYWNlIEFsbEJhbGFuY2VkVHJlZXMKewogICAgY2xhc3MgUHJvZ3JhbQogICAgewogICAgICAgIHN0YXRpYyB2b2lkIE1haW4oc3RyaW5nW10gYXJncykKICAgICAgICB7CiAgICAgICAgICAgIGNoYXJbXSBub2RlcyA9IHsgJ0EnLCAnQicsICdDJywgJ0QnLCAnRScgfTsKCiAgICAgICAgICAgIEFsbEJhbGFuY2VkVHJlZXM8Y2hhcj4gQWxsQmFsYW5jZWRUcmVlcyA9IG5ldyBBbGxCYWxhbmNlZFRyZWVzPGNoYXI+KCk7IAoKICAgICAgICAgICAgZm9yZWFjaCAoY2hhcltdIGEgaW4gQWxsQmFsYW5jZWRUcmVlcy5hbGxCYWxhbmNlZFRyZWVDb21iaW5hdGlvbnMobm9kZXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3JlYWNoIChjaGFyIGMgaW4gYSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBDb25zb2xlLldyaXRlKGMgKyAiICIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgQ29uc29sZS5Xcml0ZUxpbmUoKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgQ29uc29sZS5SZWFkS2V5KCk7CiAgICAgICAgfQogICAgfQoKICAgIGNsYXNzIEFsbEJhbGFuY2VkVHJlZXM8VD4KICAgIHsKICAgICAgICBwdWJsaWMgSUVudW1lcmFibGU8VFtdPiBhbGxCYWxhbmNlZFRyZWVDb21iaW5hdGlvbnMoVFtdIG5vZGVzKQogICAgICAgIHsKICAgICAgICAgICAgVFtdIHJlc3VsdDsKICAgICAgICAgICAgaWYgKG5vZGVzLkxlbmd0aCA9PSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB5aWVsZCByZXR1cm4gbm9kZXM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAobm9kZXMuTGVuZ3RoID09IDIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHlpZWxkIHJldHVybiBub2RlczsKICAgICAgICAgICAgICAgIFRbXSBub2RlczIgPSBuZXcgVFsyXTsKICAgICAgICAgICAgICAgIG5vZGVzMlswXSA9IG5vZGVzWzFdOwogICAgICAgICAgICAgICAgbm9kZXMyWzFdID0gbm9kZXNbMF07CiAgICAgICAgICAgICAgICB5aWVsZCByZXR1cm4gbm9kZXMyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKG5vZGVzLkxlbmd0aCAlIDIgPT0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IG1pZCA9IChub2Rlcy5MZW5ndGggLSAxKSAvIDI7CiAgICAgICAgICAgICAgICBUW10gbGVmdCA9IG5ldyBUW21pZF07CiAgICAgICAgICAgICAgICBUW10gcmlnaHQgPSBuZXcgVFttaWRdOwogICAgICAgICAgICAgICAgQXJyYXkuQ29weShub2RlcywgMCwgbGVmdCwgMCwgbWlkKTsKICAgICAgICAgICAgICAgIEFycmF5LkNvcHkobm9kZXMsIG1pZCArIDEsIHJpZ2h0LCAwLCBtaWQpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoVFtdIGwgaW4gYWxsQmFsYW5jZWRUcmVlQ29tYmluYXRpb25zKGxlZnQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKFRbXSByIGluIGFsbEJhbGFuY2VkVHJlZUNvbWJpbmF0aW9ucyhyaWdodCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgVFtub2Rlcy5MZW5ndGhdOwogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbMF0gPSBub2Rlc1ttaWRdOwogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoIChUW10gYSBpbiBhbGxNZXJnZUNvbWJpbmF0aW9ucyhsLCByKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXkuQ29weShhLCAwLCByZXN1bHQsIDEsIGEuTGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlpZWxkIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgbWlkID0gKG5vZGVzLkxlbmd0aCkgLyAyOwogICAgICAgICAgICAgICAgVFtdIGxlZnQgPSBuZXcgVFttaWRdOwogICAgICAgICAgICAgICAgVFtdIHJpZ2h0ID0gbmV3IFRbbWlkIC0gMV07CiAgICAgICAgICAgICAgICBBcnJheS5Db3B5KG5vZGVzLCAwLCBsZWZ0LCAwLCBtaWQpOwogICAgICAgICAgICAgICAgQXJyYXkuQ29weShub2RlcywgbWlkICsgMSwgcmlnaHQsIDAsIG1pZCAtIDEpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoVFtdIGwgaW4gYWxsQmFsYW5jZWRUcmVlQ29tYmluYXRpb25zKGxlZnQpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvcmVhY2ggKFRbXSByIGluIGFsbEJhbGFuY2VkVHJlZUNvbWJpbmF0aW9ucyhyaWdodCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgVFtub2Rlcy5MZW5ndGhdOwogICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbMF0gPSBub2Rlc1ttaWRdOwogICAgICAgICAgICAgICAgICAgICAgICBmb3JlYWNoIChUW10gYSBpbiBhbGxNZXJnZUNvbWJpbmF0aW9ucyhsLCByKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXkuQ29weShhLCAwLCByZXN1bHQsIDEsIGEuTGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlpZWxkIHJldHVybiByZXN1bHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgbWlkID0gbm9kZXMuTGVuZ3RoIC8gMiAtIDE7CiAgICAgICAgICAgICAgICBsZWZ0ID0gbmV3IFRbbWlkXTsKICAgICAgICAgICAgICAgIHJpZ2h0ID0gbmV3IFRbbWlkICsgMV07CiAgICAgICAgICAgICAgICBBcnJheS5Db3B5KG5vZGVzLCAwLCBsZWZ0LCAwLCBtaWQpOwogICAgICAgICAgICAgICAgQXJyYXkuQ29weShub2RlcywgbWlkICsgMSwgcmlnaHQsIDAsIG1pZCsxKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKFRbXSBsIGluIGFsbEJhbGFuY2VkVHJlZUNvbWJpbmF0aW9ucyhsZWZ0KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3JlYWNoIChUW10gciBpbiBhbGxCYWxhbmNlZFRyZWVDb21iaW5hdGlvbnMocmlnaHQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFRbbm9kZXMuTGVuZ3RoXTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0WzBdID0gbm9kZXNbbWlkXTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAoVFtdIGEgaW4gYWxsTWVyZ2VDb21iaW5hdGlvbnMobCwgcikpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5LkNvcHkoYSwgMCwgcmVzdWx0LCAxLCBhLkxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5aWVsZCByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHB1YmxpYyBJRW51bWVyYWJsZTxUW10+IGFsbE1lcmdlQ29tYmluYXRpb25zKFRbXSBmaXJzdEFycmF5LCBUW10gc2Vjb25kQXJyYXkpCiAgICAgICAgewogICAgICAgICAgICBpZiAoZmlyc3RBcnJheS5MZW5ndGggPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgeWllbGQgcmV0dXJuIHNlY29uZEFycmF5OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKHNlY29uZEFycmF5Lkxlbmd0aCA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB5aWVsZCByZXR1cm4gZmlyc3RBcnJheTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRbXSByZXN1bHQ7CgogICAgICAgICAgICAgICAgVFtdIGZpcnN0TWludXNPbmU7CiAgICAgICAgICAgICAgICBmaXJzdE1pbnVzT25lID0gbmV3IFRbZmlyc3RBcnJheS5MZW5ndGggLSAxXTsKICAgICAgICAgICAgICAgIEFycmF5LkNvcHkoZmlyc3RBcnJheSwgMSwgZmlyc3RNaW51c09uZSwgMCwgZmlyc3RNaW51c09uZS5MZW5ndGgpOwogICAgICAgICAgICAgICAgZm9yZWFjaCAoVFtdIGEgaW4gYWxsTWVyZ2VDb21iaW5hdGlvbnMoZmlyc3RNaW51c09uZSwgc2Vjb25kQXJyYXkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBUW2ZpcnN0QXJyYXkuTGVuZ3RoICsgc2Vjb25kQXJyYXkuTGVuZ3RoXTsKICAgICAgICAgICAgICAgICAgICByZXN1bHRbMF0gPSBmaXJzdEFycmF5WzBdOwogICAgICAgICAgICAgICAgICAgIEFycmF5LkNvcHkoYSwgMCwgcmVzdWx0LCAxLCBhLkxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgeWllbGQgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBUW10gc2Vjb25kTWludXNPbmU7CiAgICAgICAgICAgICAgICBzZWNvbmRNaW51c09uZSA9IG5ldyBUW3NlY29uZEFycmF5Lkxlbmd0aCAtIDFdOwogICAgICAgICAgICAgICAgQXJyYXkuQ29weShzZWNvbmRBcnJheSwgMSwgc2Vjb25kTWludXNPbmUsIDAsIHNlY29uZE1pbnVzT25lLkxlbmd0aCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoIChUW10gYSBpbiBhbGxNZXJnZUNvbWJpbmF0aW9ucyhmaXJzdEFycmF5LCBzZWNvbmRNaW51c09uZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gbmV3IFRbZmlyc3RBcnJheS5MZW5ndGggKyBzZWNvbmRBcnJheS5MZW5ndGhdOwogICAgICAgICAgICAgICAgICAgIHJlc3VsdFswXSA9IHNlY29uZEFycmF5WzBdOwogICAgICAgICAgICAgICAgICAgIEFycmF5LkNvcHkoYSwgMCwgcmVzdWx0LCAxLCBhLkxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgeWllbGQgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0K