tree.txx 2.8 KB

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