tree.txx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. root_node=new Node_t();
  20. root_node->Initialize(NULL,0,init_data_);
  21. }
  22. template <class TreeNode>
  23. void Tree<TreeNode>::RefineTree(){
  24. Node_t* curr_node;
  25. curr_node=PostorderFirst();
  26. while(curr_node!=NULL){
  27. if(!curr_node->IsLeaf())
  28. if(!curr_node->SubdivCond()) curr_node->Truncate();
  29. curr_node=PostorderNxt(curr_node);
  30. }
  31. curr_node=PreorderFirst();
  32. while(curr_node!=NULL){
  33. if(curr_node->IsLeaf())
  34. if(curr_node->SubdivCond())
  35. curr_node->Subdivide();
  36. curr_node=PreorderNxt(curr_node);
  37. }
  38. }
  39. template <class TreeNode>
  40. TreeNode* Tree<TreeNode>::PreorderFirst(){
  41. return root_node;
  42. }
  43. template <class TreeNode>
  44. TreeNode* Tree<TreeNode>::PreorderNxt(Node_t* curr_node){
  45. assert(curr_node!=NULL);
  46. int n=(1UL<<dim);
  47. if(!curr_node->IsLeaf())
  48. for(int i=0;i<n;i++)
  49. if(curr_node->Child(i)!=NULL)
  50. return (Node_t*)curr_node->Child(i);
  51. Node_t* node=curr_node;
  52. while(true){
  53. int i=node->Path2Node()+1;
  54. node=(Node_t*)node->Parent();
  55. if(node==NULL) return NULL;
  56. for(;i<n;i++)
  57. if(node->Child(i)!=NULL)
  58. return (Node_t*)node->Child(i);
  59. }
  60. }
  61. template <class TreeNode>
  62. TreeNode* Tree<TreeNode>::PostorderFirst(){
  63. Node_t* node=root_node;
  64. int n=(1UL<<dim);
  65. while(true){
  66. if(node->IsLeaf()) return node;
  67. for(int i=0;i<n;i++)
  68. if(node->Child(i)!=NULL){
  69. node=(Node_t*)node->Child(i);
  70. break;
  71. }
  72. }
  73. }
  74. template <class TreeNode>
  75. TreeNode* Tree<TreeNode>::PostorderNxt(Node_t* curr_node){
  76. assert(curr_node!=NULL);
  77. Node_t* node=curr_node;
  78. int j=node->Path2Node()+1;
  79. node=(Node_t*)node->Parent();
  80. if(node==NULL) return NULL;
  81. int n=(1UL<<dim);
  82. for(;j<n;j++){
  83. if(node->Child(j)!=NULL){
  84. node=(Node_t*)node->Child(j);
  85. while(true){
  86. if(node->IsLeaf()) return node;
  87. for(int i=0;i<n;i++)
  88. if(node->Child(i)!=NULL){
  89. node=(Node_t*)node->Child(i);
  90. break;
  91. }
  92. }
  93. }
  94. }
  95. return node;
  96. }
  97. template <class TreeNode>
  98. std::vector<TreeNode*>& Tree<TreeNode>::GetNodeList(){
  99. if(root_node->GetStatus() & 1){
  100. node_lst.clear();
  101. TreeNode* n=this->PreorderFirst();
  102. while(n!=NULL){
  103. int& status=n->GetStatus();
  104. status=(status & (~(int)1));
  105. node_lst.push_back(n);
  106. n=this->PreorderNxt(n);
  107. }
  108. }
  109. return node_lst;
  110. }
  111. }//end namespace