{"id":16309781,"url":"https://github.com/w1th0utnam3/undirected_graph","last_synced_at":"2025-06-14T06:40:01.317Z","repository":{"id":33980180,"uuid":"37727626","full_name":"w1th0utnam3/undirected_graph","owner":"w1th0utnam3","description":"A simple (probably incomplete) implementation of an undirected graph in c++ using the stl.","archived":false,"fork":false,"pushed_at":"2016-03-30T21:53:29.000Z","size":294,"stargazers_count":5,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-03T16:07:43.248Z","etag":null,"topics":["container","graph","traversal","vertices"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/w1th0utnam3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-19T14:52:42.000Z","updated_at":"2022-02-02T11:28:32.000Z","dependencies_parsed_at":"2022-07-13T17:10:41.816Z","dependency_job_id":null,"html_url":"https://github.com/w1th0utnam3/undirected_graph","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/w1th0utnam3%2Fundirected_graph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/w1th0utnam3%2Fundirected_graph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/w1th0utnam3%2Fundirected_graph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/w1th0utnam3%2Fundirected_graph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/w1th0utnam3","download_url":"https://codeload.github.com/w1th0utnam3/undirected_graph/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247157047,"owners_count":20893202,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["container","graph","traversal","vertices"],"created_at":"2024-10-10T21:22:33.290Z","updated_at":"2025-04-04T09:41:21.289Z","avatar_url":"https://github.com/w1th0utnam3.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# undirected_graph\nA simple implementation of an undirected graph in c++ using the stl.\n\nDuring my work on a group assignment in university I was in need for a graph\ncontainer with methods for breadth/depth-first traversal. I quickly found the\nimplementation of the boost library (http://www.boost.org/doc/libs/1_58_0/libs/graph/doc/)\nbut I did not want to use a premade solution immediately. As optimal performance\nwas not required, I decided to develop my own container with corresponding\ntraversal iterators.\n\nIf you have ideas for improvements or find bugs, feel free to notify me about\nthem!\n\nThe project is licensed under the GNU GPL v2 license. Have a look into the\nLICENSE file for more information.\n\n## Quickstart\n\nTo start using the `undirect_graph` simply include the `.h` files in your\nproject and instantiate the graph with the corresponding template arguments:\n```c++\ntemplate \u003cclass Key_vertex, class T_vertex,\n\t\t  class Key_edge, class T_edge\u003e\nclass undirected_graph;\n```\nwhere `T_vertex`/`T_edge` are the datatypes that are stored at the\nvertices/edges  and `Key_vertex`/`Key_edge` are the identifier types used to\nretrieve or remove objects from the graph.\nThe `Key_edge` type has to meet certain criteria, for an easy start use the\nsupplied `undirected_pair\u003cT\u003e` where `T` would be the `Key_vertex` type of the\ngraph.\n```c++\ntemplate \u003ctypename T\u003e\nclass undirected_pair;\n```\nMost of the time you can use `int` or `size_t` as the `Key_vertex` type and\n`undirected_pair\u003cint\u003e` or respectively `undirected_pair\u003csize_t\u003e` as the\n`Key_edge` type. If you want to use your own id types (maybe you already have\nids for the objects in your code) make sure to check the requirements some\nparagraphs below.\n\nNote: The header files require C++11 to compile.\n\n## Features\n\nThe graph allows to store vertex data types with unique ids which are connected\nby edge data objects which have in turn unique ids. Naturally the graph is\nimplemented using templates and therefore every data type is supported.\n\nIn most operations the graph behaves similar to the `std::map` container because\n(a) it is built using maps and (b) it's what you're probably used to after\nworking with stl containers. The only difference is that most methods have an\nappended `_vertex` or `_edge` to indicate on which objects the method works.\n\nIt is possible to:\n - add vertex data with a unique id\n - add edge data by specifying two vertex ids that aren't already connected\n - access the data by reference using the corresponding id\n - remove vertices and egdes by id\n - iterate through all vertices or edges (unordered)\n - iterate through all adjacent vertices of a vertex with a specified id\n - iterate through the graph vertices by using an breadth- or depth-first search\n   iterator\n\nSome example code:\n```c++\ntypedef undirected_graph\u003csize_t, std::string, undirected_pair\u003csize_t\u003e, double\u003e graph_type;\ngraph_type graph;\n\n// Build graph\ngraph.insert_vertex(1, \"Hello world!\");\ngraph.insert_vertex(2, \"Some more text.\");\ngraph.insert_vertex(3, \"Hi\");\ngraph.insert_edge(1, 2, 44.12);\ngraph.insert_edge(2, 3, 22.34);\n\n// Print edge data\nfor(auto it = graph.begin_edges(); it != graph.end_edges(); ++it) {\n\t\tstd::cout \u003c\u003c \"Connection\" \u003c\u003c it-\u003efirst.a \u003c\u003c \"to\" \u003c\u003c it-\u003efirst.b\n\t\t\t\t  \u003c\u003c \"with value:\" \u003c\u003c it-\u003esecond \u003c\u003c std::endl;\n}\n\nbreadth_first_iterator\u003cgraph_type\u003e bfs(graph, graph.find_vertex(1));\n// Iterate through the graph and print the strings\nwhile(!bfs.end()) {\n\tstd::cout \u003c\u003c bfs.next()-\u003esecond \u003c\u003c std::endl\n}\n\n// Remove a vertex and its edge(s)\ngraph.erase_vertex(2);\n```\nYou can find more example code in the `main.cpp` in the test subfolder.\n\n## What does this project contain?\n\nThe project consist mainly of three parts:\n- `undirected_graph` the main component of the graph I've been writing about\n  this whole document.\n- `undirected_pair` a simple data type which behaves similar to a `std::pair`\n  except for the fact that it is just for one data type, pair(a,b) and pair(b,a)\n  compare as equal and it's sortable. The sorting order is determined by the\n  smaller and bigger elements of the pairs. It's a simple data type to use for\n\tthe edge ids in the graph.\n- `graph_search_iterator` is an abstract class that provides an interface for\n  graph traversal iterators. Two subclasses are supplied: a breadth-first and a\n  depth-first iterator.\n\n## Requirements for the data types\n\nThere are no requirements or restrictions on the data types supplied as\n`T_vertex` or `T_edge`. However there are some requirements for\nthe id types.\n\n`Key_vertex` basically has to fulfil the same requirements as a key for an\n`std::unordered_set` and a `std::map`. Namely:\n- Equality operator `==`\n- Strict weak ordering operator `\u003c`\n- Specialized `std::hash` functor (see http://stackoverflow.com/a/17017281/929037)\n\nThe same applies to the `Key_edge` with some more restrictions:\n- Additional constructor with the signature `edge_id(vertex_id a, vertex_id b)`\n- Equality operator where `edge_id(a,b) == edge_id(b,a)` (this also affects the\n\t`\u003c`-operator and hash functor, see below)\n- Access to the two connected `vertex_id`s via a public `a` and `b` member\n\nFor a data type that implements all these requirements have a look at the\n`undirected_pair`. Nevertheless here are the axioms for the `\u003c`-operator of the\n`Key_edge`:\n```\nLet a, b, c, d be of type vertex_id and idA(a,b), idB(c,d) be of type edge_id. Then:\n1. min(a,b) \u003c min(c,d) then: (idA \u003c idB)\n2. If not 1 and min(c,d) \u003c min(a,b) then: (idB \u003c idA)\n3. If not 1 and not 2 and max(a,b) \u003c max(c,d) then: (idA \u003c idB)\n4. If not 1 and not 2 and not 3 then: not (idA \u003c idB)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fw1th0utnam3%2Fundirected_graph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fw1th0utnam3%2Fundirected_graph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fw1th0utnam3%2Fundirected_graph/lists"}