Parker Schuh | 6691f19 | 2017-01-14 17:01:02 -0800 | [diff] [blame] | 1 | #ifndef _AOS_VISION_BLOB_DISJOINT_SET_H_ |
| 2 | #define _AOS_VISION_BLOB_DISJOINT_SET_H_ |
| 3 | |
| 4 | #include <vector> |
| 5 | |
| 6 | namespace aos { |
| 7 | namespace vision { |
| 8 | |
Brian Silverman | b27e6b7 | 2019-03-10 16:17:42 -0700 | [diff] [blame] | 9 | // Disjoint set algorithm, which is similar to what this class does: |
Parker Schuh | 6691f19 | 2017-01-14 17:01:02 -0800 | [diff] [blame] | 10 | // https://en.wikipedia.org/wiki/Disjoint-set_data_structure |
| 11 | class DisjointSet { |
| 12 | public: |
| 13 | DisjointSet() {} |
| 14 | DisjointSet(int node_count) : nodes_(node_count, -1) {} |
| 15 | // Adds another node. Not connected to anything. |
| 16 | // Returns id of the additional node for tracking purposes. |
| 17 | int Add() { |
| 18 | nodes_.push_back(-1); |
| 19 | return nodes_.size() - 1; |
| 20 | } |
| 21 | int &operator[](int id) { return nodes_[id]; } |
| 22 | // Find returns the canonical id of the set containing id. |
| 23 | // This id is an arbitrary artifact of the merge process. |
| 24 | int Find(int id) { |
| 25 | int chained_id = nodes_[id]; |
| 26 | if (chained_id <= -1) { |
| 27 | return id; |
| 28 | } |
| 29 | return nodes_[id] = Find(chained_id); |
| 30 | } |
| 31 | // The blob mergeing needs to explicitly override the default union behavior. |
| 32 | void ExplicitUnion(int parent_id, int child_id) { |
| 33 | nodes_[parent_id] = child_id; |
| 34 | } |
| 35 | // Check to see if this node is the canonical id. |
| 36 | bool IsRoot(int id) { return nodes_[id] < 0; } |
| 37 | |
| 38 | private: |
| 39 | // Implemented over a vector. |
| 40 | std::vector<int> nodes_; |
| 41 | }; |
| 42 | |
| 43 | } // namespace vision |
| 44 | } // namespace aos |
| 45 | |
| 46 | #endif // _AOS_VISION_BLOB_DISJOINT_SET_H_ |