//-----------------------------------------------------------------------------// // Tree 메모리제거 //-----------------------------------------------------------------------------// void ReleaseTree( C3dNode *pTree ) { if( !pTree ) return; ReleaseTree( pTree->m_pChild ); ReleaseTree( pTree->m_pNext ); delete pTree; }
void ReleaseTree(TreeNode* root) { if(root == NULL) return; ReleaseTree(root->left); ReleaseTree(root->right); delete root; root = NULL; }
vector<TreeNode*> generateTreesInternal(int n) { vector<TreeNode*> ret; if(n == 0) { ret.push_back(NULL); return ret; } if(n == 1) { ret.push_back(new TreeNode(1)); return ret; } for(int i = 0; i <= n - 1; ++i) { vector<TreeNode*> leftRoot = generateTreesInternal(i); vector<TreeNode*> rightRoot = generateTreesInternal(n-1-i); for(int i = 0; i < leftRoot.size(); ++i) { for(int j = 0; j < rightRoot.size(); ++j) { TreeNode* root = new TreeNode(i+1); root->left = CopyTree(leftRoot[i]); root->right = CopyTree(rightRoot[j]); ret.push_back(root); } } for(int i = 0; i < leftRoot.size(); ++i) { ReleaseTree(leftRoot[i]); } for(int i = 0; i < rightRoot.size(); ++i) { ReleaseTree(rightRoot[i]); } } return ret; }
// Release the memory for binary tree. void CollageBasic::ReleaseTree(TreeNode* node) { if (node == NULL) return; if (node->left_child_) ReleaseTree(node->left_child_); if (node->right_child_) ReleaseTree(node->right_child_); delete node; }
// Generate an initial full binary tree with image_num_ leaves. bool CollageBasic::GenerateInitialTree() { tree_leaves_.clear(); if (tree_root_ != NULL) ReleaseTree(tree_root_); tree_root_ = new TreeNode(); // Step 1: create a (k-1)-depth binary tree with max nodes. // 2 ^ (k - 1) <= m < 2 ^ k int m = image_num_; assert(m != 0); int k = 0; while (m != 0) { m >>= 1; ++k; } std::vector<std::vector<TreeNode*>> node_queue; for (int i = 0; i < k; ++i) { std::vector<TreeNode*> node_queue_temp; node_queue.push_back(node_queue_temp); } node_queue[0].push_back(tree_root_); for (int i = 0; i < k - 1; ++i) { for (int j = 0; j < pow(2, i); ++j) { node_queue[i][j]->left_child_ = new TreeNode(); node_queue[i][j]->left_child_->child_type_ = 'l'; node_queue[i][j]->left_child_->parent_ = node_queue[i][j]; node_queue[i + 1].push_back(node_queue[i][j]->left_child_); node_queue[i][j]->right_child_ = new TreeNode(); node_queue[i][j]->right_child_->child_type_ = 'r'; node_queue[i][j]->right_child_->parent_ = node_queue[i][j]; node_queue[i + 1].push_back(node_queue[i][j]->right_child_); node_queue[i][j]->is_leaf_ = false; } } std::vector<TreeNode*> leaf_nodes; for (int i = 0; i < node_queue[k - 1].size(); ++i) { leaf_nodes.push_back(node_queue[k - 1][i]); }; int leaf_num = pow(2, k - 1); bool* leaf_visited = new bool[leaf_num]; for (int i = 0; i < leaf_num; ++i) leaf_visited[i] = false; assert(static_cast<int>(leaf_nodes.size()) == leaf_num); // Step 2: randomly select image_num_ - 2 ^ (k - 1) leaves, // split them with left and right children. Then, you have a // full balanced binary tree with image_num_ leaves. int left_leaves = image_num_ - leaf_num; int counter = 0; while (counter < left_leaves) { int rand_ind = random(left_leaves); if (leaf_visited[rand_ind] == true) continue; leaf_visited[rand_ind] = true; leaf_nodes[rand_ind]->is_leaf_ = false; leaf_nodes[rand_ind]->left_child_ = new TreeNode(); leaf_nodes[rand_ind]->left_child_->child_type_ = 'l'; leaf_nodes[rand_ind]->left_child_->parent_ = leaf_nodes[rand_ind]; leaf_nodes[rand_ind]->right_child_ = new TreeNode(); leaf_nodes[rand_ind]->right_child_->child_type_ = 'r'; leaf_nodes[rand_ind]->right_child_->parent_ = leaf_nodes[rand_ind]; tree_leaves_.push_back(leaf_nodes[rand_ind]->left_child_); tree_leaves_.push_back(leaf_nodes[rand_ind]->right_child_); ++counter; } for (int i = 0; i < leaf_num; ++i) { if (leaf_visited[i] != true) tree_leaves_.push_back(leaf_nodes[i]); } // Now we have created a binary tree with image_num_ leaves. // And the vector leaf_nodes_new stores all the leaf nodes. assert(static_cast<int>(tree_leaves_.size()) == image_num_); delete [] leaf_visited; leaf_nodes.clear(); // Step 3: random dispatch images to leaf nodes. bool* img_visited = new bool[image_num_]; for (int i = 0; i < image_num_; ++i) img_visited[i] = false; counter = 0; while (counter < image_num_) { int rand_img_ind = random(image_num_); if (img_visited[rand_img_ind] == true) continue; img_visited[rand_img_ind] = true; // Set the related image index and aspect ratio for leaf nodes. tree_leaves_[counter]->image_index_ = rand_img_ind; tree_leaves_[counter]->alpha_ = image_alpha_vec_[rand_img_ind]; ++counter; } delete [] img_visited; // Step 4: assign a random 'v' or 'h' for all the inner nodes. RandomSplitType(tree_root_); return true; }
TreeNode::~TreeNode() { if (count) ReleaseTree(); }