求满二叉树两个节点之间的最短距离  
 
 
using  System ; 
using  System. Collections. Generic ; 
using  System. Linq ; 
using  System. Text ; namespace  FirstSolver 
{ internal  class  Program { static  void Main ( string [ ] ) { BinaryTreeNode< int >   root1 =  FullBinaryTree. CreateTree ( 1 ,  4 ) ; Console. WriteLine ( FullBinaryTree. PrintTree ( root1) ) ; Console. WriteLine ( ) ; BinaryTreeNode< int >   root2 =  FullBinaryTree. CreateTree ( 101 ,  4 ) ; Console. WriteLine ( FullBinaryTree. PrintTree ( root2) ) ; Console. WriteLine ( ) ; BinaryTreeNode< int >   root3 =  FullBinaryTree. CreateTree ( 201 ,  4 ) ; Console. WriteLine ( FullBinaryTree. PrintTree ( root3) ) ; Console. WriteLine ( ) ; root1. ParentNode =  root2; root2. ParentNode =  root3; root3. ParentNode =  root1; BinaryTreeNode< int >   nodeA =  FullBinaryTree. FindNode ( root1,  5 ) ; BinaryTreeNode< int >   nodeB =  FullBinaryTree. FindNode ( root1,  7 ) ; Console. WriteLine ( $"[A( { nodeA. Value } )]->[B( { nodeB. Value } )]" ) ; Stack< BinaryTreeNode< int > >   path =  FullBinaryTree. FindPath ( nodeA,  nodeB) ; Console. WriteLine ( FullBinaryTree. PrintPath ( path) ) ; Console. WriteLine ( FullBinaryTree. PrintPath ( FullBinaryTree. QuickFindPath ( nodeA,  nodeB) ) ) ; Console. WriteLine ( ) ; nodeB =  FullBinaryTree. FindNode ( root2,  107 ) ; Console. WriteLine ( $"[A( { nodeA. Value } )]->[B( { nodeB. Value } )]" ) ; path =  FullBinaryTree. FindPath ( nodeA,  nodeB) ; Console. WriteLine ( FullBinaryTree. PrintPath ( path) ) ; Console. WriteLine ( FullBinaryTree. PrintPath ( FullBinaryTree. QuickFindPath ( nodeA,  nodeB) ) ) ; Console. WriteLine ( ) ; nodeB =  FullBinaryTree. FindNode ( root3,  207 ) ; Console. WriteLine ( $"[A( { nodeA. Value } )]->[B( { nodeB. Value } )]" ) ; path =  FullBinaryTree. FindPath ( nodeA,  nodeB) ; Console. WriteLine ( FullBinaryTree. PrintPath ( path) ) ; Console. WriteLine ( FullBinaryTree. PrintPath ( FullBinaryTree. QuickFindPath ( nodeA,  nodeB) ) ) ; Console. WriteLine ( ) ; nodeB =  new  BinaryTreeNode< int >  ( 301 ) ; Console. WriteLine ( $"[A( { nodeA. Value } )]->[B( { nodeB. Value } )]" ) ; path =  FullBinaryTree. FindPath ( nodeA,  nodeB) ; Console. WriteLine ( FullBinaryTree. PrintPath ( path) ) ; Console. WriteLine ( FullBinaryTree. PrintPath ( FullBinaryTree. QuickFindPath ( nodeA,  nodeB) ) ) ; Console. WriteLine ( ) ; Console. ReadKey ( ) ; } } public  static  class  FullBinaryTree { public  static  BinaryTreeNode< int >   CreateTree ( int ,  int ) { BinaryTreeNode< int >   header =  new  BinaryTreeNode< int >  ( intial) ; CreateSub ( header,  intial,  2 ,  depth) ; return  header; } private  static  void CreateSub ( BinaryTreeNode< int >   node,  int ,  int ,  int ) { if  ( level >  depth)  return ; int value  =  ( node. Value <<  1 )  -  ( initial -  1 ) ; BinaryTreeNode< int >   leftChildNode =  new  BinaryTreeNode< int >  ( value ) ; BinaryTreeNode< int >   rightChildNode =  new  BinaryTreeNode< int >  ( value  +  1 ) ; node. LeftChildNode =  leftChildNode; node. RightChildNode =  rightChildNode; leftChildNode. ParentNode =  node; rightChildNode. ParentNode =  node; CreateSub ( leftChildNode,  initial,  level +  1 ,  depth) ; CreateSub ( rightChildNode,  initial,  level +  1 ,  depth) ; } public  static  string PrintTree ( BinaryTreeNode< int >   header) { StringBuilder  sb =  new  StringBuilder ( $" { header. Value } " ) ; if  ( header. LeftChildNode !=  null ) { sb. Append ( $"( { header. LeftChildNode. Value } , { header. RightChildNode. Value } )" ) ; PrintTreeSub ( header. LeftChildNode,  sb) ; PrintTreeSub ( header. RightChildNode,  sb) ; } return  sb. ToString ( ) ; } private  static  void PrintTreeSub ( BinaryTreeNode< int >   node,  StringBuilder  sb) { sb. Append ( $"  { node. Value } " ) ; if  ( node. LeftChildNode !=  null ) { sb. Append ( $"( { node. LeftChildNode. Value } , { node. RightChildNode. Value } )" ) ; PrintTreeSub ( node. LeftChildNode,  sb) ; PrintTreeSub ( node. RightChildNode,  sb) ; } } public  static  BinaryTreeNode< int >   FindNode ( BinaryTreeNode< int >   node,  int value ) { if  ( Equals ( node. Value,  value ) )  return  node; if  ( node. LeftChildNode !=  null ) { return  FindNode ( node. LeftChildNode,  value )  ??  FindNode ( node. RightChildNode,  value ) ; } return  null ; } public  static  BinaryTreeNode< int >   GetRootNode ( BinaryTreeNode< int >   node) { while  ( true ) { if  ( node. ParentNode ==  null )  break ; if  ( node. ParentNode. LeftChildNode !=  node &&  node. ParentNode. RightChildNode !=  node)  break ; node =  node. ParentNode; } return  node; } public  static  Stack< BinaryTreeNode< int > >   FindPath ( BinaryTreeNode< int >   nodeA,  BinaryTreeNode< int >   nodeB) { BinaryTreeNode< int >   rootA =  GetRootNode ( nodeA) ; Stack< BinaryTreeNode< int > >   path =  new  Stack< BinaryTreeNode< int > >  ( ) ; BinaryTreeNode< int >   node =  nodeA; path. Push ( node) ; bool =  FindPathSub ( node,  nodeB,  path) ; if  ( ! find) { while  ( ! find) { if  ( node. ParentNode ==  null )  break ; if  ( node. ParentNode ==  rootA &&  ( node !=  rootA. LeftChildNode &&  node !=  rootA. RightChildNode) )  break ; path. Push ( node. ParentNode) ; int =  0 ;  if  ( node. ParentNode. LeftChildNode ==  node) state =  1 ; else  if  ( node. ParentNode. RightChildNode ==  node) state =  2 ; if  ( state ==  0  ||  state ==  1 ) { find =  FindPathSub ( node. ParentNode. RightChildNode,  nodeB,  path) ; if  ( find)  break ; } if  ( state ==  0  ||  state ==  2 ) { find =  FindPathSub ( node. ParentNode. LeftChildNode,  nodeB,  path) ; if  ( find)  break ; } node =  node. ParentNode; } } return  find ?   path :  null ; } private  static  bool FindPathSub ( BinaryTreeNode< int >   node,  BinaryTreeNode< int >   search,  Stack< BinaryTreeNode< int > >   path) { path. Push ( node) ; if  ( node ==  search)  return  true ; if  ( node. LeftChildNode !=  null ) { if  ( FindPathSub ( node. LeftChildNode,  search,  path) )  return  true ; if  ( FindPathSub ( node. RightChildNode,  search,  path) )  return  true ; } path. Pop ( ) ; return  false ; } public  static  List< BinaryTreeNode< int > >   GetRootNodePath ( BinaryTreeNode< int >   node) { List< BinaryTreeNode< int > >   path =  new  List< BinaryTreeNode< int > >  ( ) ; path. Add ( node) ; while  ( true ) { if  ( node. ParentNode ==  null )  break ; if  ( node. ParentNode. LeftChildNode !=  node &&  node. ParentNode. RightChildNode !=  node)  break ; node =  node. ParentNode; path. Add ( node) ; } return  path; } public  static  List< BinaryTreeNode< int > >   QuickFindPath ( BinaryTreeNode< int >   nodeA,  BinaryTreeNode< int >   nodeB) { List< BinaryTreeNode< int > >   pathA =  GetRootNodePath ( nodeA) ; List< BinaryTreeNode< int > >   pathB =  GetRootNodePath ( nodeB) ; BinaryTreeNode< int >   rootA =  pathA[ pathA. Count -  1 ] ; BinaryTreeNode< int >   rootB =  pathB[ pathB. Count -  1 ] ; if  ( rootA ==  rootB) { int =  pathA. Count -  2 ; int =  pathB. Count -  2 ; for  ( ;  i >=  0  &&  j >=  0 ;  i-- ,  j-- ) { if  ( pathA[ i]  !=  pathB[ j] )  break ; } if  ( pathA. Count -  2  >  i)  pathA. RemoveRange ( i +  2 ,  pathA. Count -  i -  2 ) ; pathB. RemoveRange ( j +  1 ,  pathB. Count -  j -  1 ) ; pathB. Reverse ( ) ; pathA. AddRange ( pathB) ; return  pathA; } else { BinaryTreeNode< int >   node =  rootA; while  ( node. ParentNode !=  null ) { node =  node. ParentNode; if  ( node ==  rootB) { pathB. Reverse ( ) ; pathA. AddRange ( pathB) ; return  pathA; } else  if  ( node ==  rootA) {    break ; } pathA. Add ( node) ; } return  null ; }             } public  static  string PrintPath ( IEnumerable< BinaryTreeNode< int > >   path) { if  ( path ==  null )  return  "No Path!" ;  IEnumerable< BinaryTreeNode< int > >   p =  path; if  ( path is  Stack< BinaryTreeNode< int > >  ) { p =  p. Reverse ( ) ; }             StringBuilder  sb =  new  StringBuilder ( ) ; foreach  ( var in  p) { sb. Append ( $" { item. Value } ->" ) ; } sb. Remove ( sb. Length -  2 ,  2 ) ; return  sb. ToString ( ) ; } } public  class  BinaryTreeNode< T>   where  T  :  struct { public  T  Value {  get ;  set ;  } public  BinaryTreeNode< T>   ParentNode {  get ;  set ;  } public  BinaryTreeNode< T>   LeftChildNode {  get ;  set ;  } public  BinaryTreeNode< T>   RightChildNode {  get ;  set ;  } public  BinaryTreeNode ( )  {  Value =  default ;  } public  BinaryTreeNode ( T  value )  {  Value =  value ;  } } 
}