template<class T> parentChildren windowManager::deleteIndexedImageFromList(QList<T>* list, int index) { for (int i = 0, size = list->size(); i < size; ++i) { T& thisItem = (*list)[i]; // a modifiable reference if (thisItem.index() == index) { if (thisItem.hasChildren()) { thisItem.setHidden(true); return parentChildren(-1, -1); } else { const int parent = thisItem.parent(); list->removeAt(i); return parentChildren(index, parent); } } } return parentChildren(-1, -1); }
template<class T> parentChildren windowManager::childDeletedFromList(QList<T>* list, int thisIndex, int childIndex) { for (int i = 0, size = list->size(); i < size; ++i) { T& thisItem = (*list)[i]; // a modifiable reference if (thisItem.index() == thisIndex) { thisItem.removeChild(childIndex); if (!thisItem.hasChildren() && thisItem.hidden()) { list->removeAt(i); const int parent = thisItem.parent(); return parentChildren(thisIndex, parent); } else { return parentChildren(-1, -1); } } } return parentChildren(-1, -1); }
void executeBurstFlower(Flower *greenFlower) { // Find the subflower that connects to the parent. Flower *upperSubFlower(nullptr); { // Find the edge that connects to the parent. Edge *parentEdge(nullptr); STD_VECTOR_FOREACH_(Edge *, greenFlower->parent->edges, edgeIt, edgeEnd) { Edge *edge(*edgeIt); if (edge->type == Edge::Type::FULL_BLOCKING) { const std::vector<Flower *> &edgeFlowers(edge->flowers); if (std::find(edgeFlowers.begin(), edgeFlowers.end(), greenFlower) != edgeFlowers.end()) { parentEdge = edge; break; } } } const std::vector<Flower *> &parentEdgeFlowers(parentEdge->flowers); // Find the subflower that connects to the edge that connects to the parent. STD_VECTOR_FOREACH_(Flower *, greenFlower->subFlowers, flowerIt, flowerEnd) { upperSubFlower = *flowerIt; if (std::find(parentEdgeFlowers.begin(), parentEdgeFlowers.end(), upperSubFlower) != parentEdgeFlowers.end()) { break; } } } // Find the subflower that contains the stem vertex. Flower *lowerSubFlower(greenFlower->stemSubFlower); // Initialize variables for sub flower reordering. std::vector<Flower *> greenFlowerSubFlowers(greenFlower->subFlowers); int upperSubFlowerId(0); int lowerSubFlowerId(0); int subFlowersCount(static_cast<int>(greenFlowerSubFlowers.size())); // Find the indices of the upper and lower subflowers. for (int i(0); i < subFlowersCount; ++i) { if (greenFlowerSubFlowers[i] == upperSubFlower) { upperSubFlowerId = i; } if (greenFlowerSubFlowers[i] == lowerSubFlower) { lowerSubFlowerId = i; } } // Reorder green subflowers. // The first flower becomes the upper subflower, then follows an odd number of flowers, // then follows the lower subflower, then follows an even number of flowers. reorderFlowers(greenFlowerSubFlowers, upperSubFlowerId, lowerSubFlowerId); // Replace the green flower in the connection with its parent by the upper sub flower. { // Remove the green flower from its parent's children. std::vector<Flower *> &parentChildren(greenFlower->parent->children); parentChildren.erase(std::remove(parentChildren.begin(), parentChildren.end(), greenFlower), parentChildren.end()); // Add the upper sub flower to the parent's children. parentChildren.push_back(upperSubFlower); // Set the green flower's parent as the upper sub flower's parent. upperSubFlower->parent = greenFlower->parent; } // Replace the green flower in the connection with its child by the lower sub flower. { Flower *greenFlowerChild(greenFlower->children.front()); // Set the lower sub flower as the parent of the green flower's child. greenFlowerChild->parent = lowerSubFlower; // Set the green flower's child as the lower sub flower's child. lowerSubFlower->children.push_back(greenFlowerChild); } // Process the segment of subflowers that remains in the tree. for (int i(upperSubFlowerId), count(lowerSubFlowerId + 1); i < count; ++i) { Flower *subFlower(greenFlowerSubFlowers[i]); subFlower->type = ((i % 2) == 0) ? Flower::Type::ODD_IN_TREE: Flower::Type::EVEN_IN_TREE; if (subFlower->parent == nullptr) { subFlower->parent = greenFlowerSubFlowers[i - 1]; } if (subFlower->children.empty()) { subFlower->children.push_back(greenFlowerSubFlowers[i + 1]); } } // Process all subflowers that become Dumbbells. for (int i(lowerSubFlowerId + 1); i < subFlowersCount; ++i) { greenFlowerSubFlowers[i]->type = Flower::Type::IN_DUMBBELL; } // Set blocking edges at the beginning and end of the tree segments as regular. setBlockingEdgeToRegular(lowerSubFlower, greenFlowerSubFlowers[(lowerSubFlowerId + 1) % subFlowersCount]); for (int i(lowerSubFlowerId + 1), count(subFlowersCount - 1); i < count; ++i) { setBlockingEdgeToRegular(greenFlowerSubFlowers[i], greenFlowerSubFlowers[i + 1]); } setBlockingEdgeToRegular(upperSubFlower, greenFlowerSubFlowers[subFlowersCount - 1]); // Remove the green flower from all edges. STD_VECTOR_FOREACH_(Edge *, greenFlower->edges, edgeIt, edgeEnd) { std::vector<Flower *> &edgeFlowers((*edgeIt)->flowers); edgeFlowers.erase(std::remove(edgeFlowers.begin(), edgeFlowers.end(), greenFlower), edgeFlowers.end()); } }
Flower *executeCreateFlower(Edge *minEdge, std::vector<Flower *> &freeFlowers) { minEdge->type = Edge::Type::FULL_BLOCKING; // Determine K flower's path to root. std::vector<Flower*> kPathToRoot; for (Flower *kFlower(freeFlowers.front()); kFlower != nullptr; kFlower = kFlower->parent) { kPathToRoot.push_back(kFlower); } // Determine H flower's path to root. std::vector<Flower*> hPathToRoot; for (Flower *hFlower(freeFlowers.back()); hFlower != nullptr; hFlower = hFlower->parent) { hPathToRoot.push_back(hFlower); } // Find the W flower, which is the LCA of K flower and H flower. Flower *wFlower(nullptr); std::vector<Flower*>::reverse_iterator kRIt(kPathToRoot.rbegin()), hRIt(hPathToRoot.rbegin()), kREnd(kPathToRoot.rend()), hREnd(hPathToRoot.rend()); for (; (kRIt != kREnd) && (hRIt != hREnd); ++kRIt, ++hRIt) { if (*kRIt != *hRIt) { break; } wFlower = *kRIt; } // Create and initialize Z flower, which is the new flower. Flower *zFlower(new Flower()); zFlower->parent = wFlower->parent; zFlower->stemSubFlower = wFlower; // Replace W flower with Z flower in Z flower's parent. if (zFlower->parent != nullptr) { std::vector<Flower *> &parentChildren(zFlower->parent->children); parentChildren.erase(std::remove(parentChildren.begin(), parentChildren.end(), wFlower), parentChildren.end()); parentChildren.push_back(zFlower); } // Populate subflowers of Z flower in the following order W, K_p, ..., K_1, K, H, H_1, ..., H_q. zFlower->subFlowers.push_back(wFlower); for (; kRIt != kREnd; ++kRIt) { zFlower->subFlowers.push_back(*kRIt); } for (std::vector<Flower*>::iterator hIt(hPathToRoot.begin()); *hIt != wFlower; ++hIt) { zFlower->subFlowers.push_back(*hIt); } // Populate children and edges of Z flower. std::vector<Flower *> zBlueFlowers(zFlower->blueSubFlowers()); STD_VECTOR_FOREACH_(Flower *, zFlower->subFlowers, subFlowerIt, subFlowerEnd) { Flower *subFlower(*subFlowerIt); // Add the children of subflowers into Z flower's children only if the child is not part of Z flower. STD_VECTOR_FOREACH_(Flower *, subFlower->children, childFlowerIt, childFlowerEnd) { Flower *childFlower(*childFlowerIt); if (std::find(zBlueFlowers.begin(), zBlueFlowers.end(), childFlower->blueStem()) == zBlueFlowers.end()) { zFlower->children.push_back(childFlower); } } // Add the edges of subflowers into Z flower's edges only if the edge is outgoing from Z flower. STD_VECTOR_FOREACH_(Edge *, subFlower->edges, subEdgeIt, subEdgeEnd) { Edge *subEdge(*subEdgeIt); bool areBothEdgeBlueFlowersInZFlower( std::find(zBlueFlowers.begin(), zBlueFlowers.end(), subEdge->blueFlowers.front()) != zBlueFlowers.end() && std::find(zBlueFlowers.begin(), zBlueFlowers.end(), subEdge->blueFlowers.back()) != zBlueFlowers.end()); if (!areBothEdgeBlueFlowersInZFlower) { zFlower->edges.push_back(subEdge); subEdge->flowers.push_back(zFlower); } } } // Replace parent in the new children of Z Flower. STD_VECTOR_FOREACH_(Flower *, zFlower->children, flowerIt, flowerEnd) { (*flowerIt)->parent = zFlower; } // Set subflower parameters. STD_VECTOR_FOREACH_(Flower *, zFlower->subFlowers, flowerIt, flowerEnd) { Flower *subflower(*flowerIt); subflower->type = Flower::Type::INTERNAL; subflower->parent = nullptr; subflower->children.clear(); } return zFlower; }