tree.txx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /**
  2. * \file tree.txx
  3. * \author Dhairya Malhotra, dhairya.malhotra@gmail.com
  4. * \date 12-11-2010
  5. * \brief This file contains the implementation of the class Tree.
  6. */
  7. namespace pvfmm{
  8. template <class TreeNode>
  9. Tree<TreeNode>::~Tree(){
  10. if(RootNode()!=NULL){
  11. delete root_node;
  12. }
  13. }
  14. template <class TreeNode>
  15. void Tree<TreeNode>::Initialize(typename Node_t::NodeData* init_data_){
  16. dim=init_data_->dim;
  17. max_depth=init_data_->max_depth;
  18. if(max_depth>MAX_DEPTH) max_depth=MAX_DEPTH;
  19. if(root_node) delete root_node;
  20. root_node=new Node_t();
  21. root_node->Initialize(NULL,0,init_data_);
  22. }
  23. template <class TreeNode>
  24. void Tree<TreeNode>::RefineTree(){
  25. Node_t* curr_node;
  26. curr_node=PostorderFirst();
  27. while(curr_node!=NULL){
  28. if(!curr_node->IsLeaf())
  29. if(!curr_node->SubdivCond()) curr_node->Truncate();
  30. curr_node=PostorderNxt(curr_node);
  31. }
  32. curr_node=PreorderFirst();
  33. while(curr_node!=NULL){
  34. if(curr_node->IsLeaf())
  35. if(curr_node->SubdivCond())
  36. curr_node->Subdivide();
  37. curr_node=PreorderNxt(curr_node);
  38. }
  39. }
  40. template <class TreeNode>
  41. TreeNode* Tree<TreeNode>::PreorderFirst(){
  42. return root_node;
  43. }
  44. template <class TreeNode>
  45. TreeNode* Tree<TreeNode>::PreorderNxt(Node_t* curr_node){
  46. assert(curr_node!=NULL);
  47. int n=(1UL<<dim);
  48. if(!curr_node->IsLeaf())
  49. for(int i=0;i<n;i++)
  50. if(curr_node->Child(i)!=NULL)
  51. return (Node_t*)curr_node->Child(i);
  52. Node_t* node=curr_node;
  53. while(true){
  54. int i=node->Path2Node()+1;
  55. node=(Node_t*)node->Parent();
  56. if(node==NULL) return NULL;
  57. for(;i<n;i++)
  58. if(node->Child(i)!=NULL)
  59. return (Node_t*)node->Child(i);
  60. }
  61. }
  62. template <class TreeNode>
  63. TreeNode* Tree<TreeNode>::PostorderFirst(){
  64. Node_t* node=root_node;
  65. int n=(1UL<<dim);
  66. while(true){
  67. if(node->IsLeaf()) return node;
  68. for(int i=0;i<n;i++)
  69. if(node->Child(i)!=NULL){
  70. node=(Node_t*)node->Child(i);
  71. break;
  72. }
  73. }
  74. }
  75. template <class TreeNode>
  76. TreeNode* Tree<TreeNode>::PostorderNxt(Node_t* curr_node){
  77. assert(curr_node!=NULL);
  78. Node_t* node=curr_node;
  79. int j=node->Path2Node()+1;
  80. node=(Node_t*)node->Parent();
  81. if(node==NULL) return NULL;
  82. int n=(1UL<<dim);
  83. for(;j<n;j++){
  84. if(node->Child(j)!=NULL){
  85. node=(Node_t*)node->Child(j);
  86. while(true){
  87. if(node->IsLeaf()) return node;
  88. for(int i=0;i<n;i++)
  89. if(node->Child(i)!=NULL){
  90. node=(Node_t*)node->Child(i);
  91. break;
  92. }
  93. }
  94. }
  95. }
  96. return node;
  97. }
  98. template <class TreeNode>
  99. std::vector<TreeNode*>& Tree<TreeNode>::GetNodeList(){
  100. if(root_node->GetStatus() & 1){
  101. node_lst.clear();
  102. TreeNode* n=this->PreorderFirst();
  103. while(n!=NULL){
  104. int& status=n->GetStatus();
  105. status=(status & (~(int)1));
  106. node_lst.push_back(n);
  107. n=this->PreorderNxt(n);
  108. }
  109. }
  110. return node_lst;
  111. }
  112. }//end namespace