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