Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.1.0)
project(Graph)

# # Debug(GDB)
# SET(CMAKE_BUILD_TYPE "Debug")
# SET(CMAKE_CXX_FLAGS_DEBUG "ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
# SET(CMAKE_CXX_FLAGS_RELEASE "ENV{CXXFLAGS} -O3 -Wall")

# Collect file
aux_source_directory(./src SRC)
include_directories(./include)

set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

# Generate lib
add_library(Graph SHARED ${SRC})

# Header file
target_include_directories(Graph
PUBLIC
./include)

# Compile
add_executable(Main main.cpp)

# Link
target_link_libraries(Main Graph)
20 changes: 20 additions & 0 deletions Introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Introduction
This project contains a shared library(`libGraph.dll`) of Graph and related algorithms. The `Main.exe` is a demo.

# Graph
Default is **Direcrted Network**. Contains both directions and weights. You can set the weight to a constant number and connect 2 vertex with 2 contary direction edge to simplify it.

## Initial
Graph contains too much information and is hard to initial by typing on keyboard. So please create a `Initial.txt` file in this
form:

```txt
A B C D E F *
A 12 E
A 1 B
C 1 A
E 2 F
```
1, First line is the vertecis data, using a '*' character as end label.

2, Following are the edges. Each line indicates an edge, left to right are tail vertex, weight, head vertex.
10 changes: 10 additions & 0 deletions include/Alias.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef __ALIAS_H__
#define __ALIAS_H__

struct Alias
{
using size_t = unsigned int;
};


#endif
33 changes: 33 additions & 0 deletions include/Edge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef __EDGE_H__
#define __EDGE_H__
#include "Alias.h"
#include "Graph.h"

// Directed edge, and has weight
class Edge : public Alias
{
friend class Graph;
private:
// The vertex that the edge comes from.
size_t tailVtx;

// The vertex that the edge comes to.
size_t headVtx;

Edge* headList;
Edge* tailList;

double weight;

public:
Edge(size_t Head_Vertex, size_t Tail_Vertex, Edge* Head_List=nullptr, Edge* Tail_list=nullptr);
~Edge();
};

Edge ::Edge(size_t Head_Vertex, size_t Tail_Vertex, Edge* Head_List, Edge* Tail_list)
:headList(Head_List), tailList(Tail_list), headVtx(Head_Vertex), tailVtx(Tail_Vertex)
{}

Edge ::~Edge()
{}
#endif
24 changes: 24 additions & 0 deletions include/Graph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef __GRAPH_H__
#define __GRAPH_H__
#include "Edge.h"
#include "Vertex.h"
#include "Alias.h"
#include <vector>
#include <iostream>
#include <string>

const std::string Path{"./../../rsrc/"};

// Using Orthogonal list
class Graph : public Alias
{
friend class Vertex;
friend class Edge;
private:
std::vector<Vertex> vertexList;

public:
Graph(std::istream& input);
~Graph();
};
#endif
33 changes: 33 additions & 0 deletions include/Vertex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef __VERTEX_H__
#define __VERTEX_H__
#include "Edge.h"
#include "Alias.h"
#include "Graph.h"

// Basic element of graph
class Vertex: public Alias
{
friend class Graph;
friend bool operator==(const Vertex& a, const Vertex& b);
private:
char data;
Edge * firstIn, *firstOut;

public:
Vertex(char Data, Edge * First_In = nullptr, Edge * First_Out = nullptr);
Vertex();
~Vertex();
};
// Support function 'std::find' work.
inline bool operator==(const Vertex& a, const Vertex& b){ return a.data == b.data; }

Vertex ::Vertex(char Data, Edge * First_In, Edge * First_Out)
:data(Data), firstIn(First_In), firstOut(First_Out)
{}

Vertex ::Vertex()
:data(), firstIn(nullptr), firstOut(nullptr){}

Vertex ::~Vertex()
{}
#endif
10 changes: 10 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "Graph.h"
#include <iostream>
#include <fstream>
// Demo

int main(){
std::ifstream in(Path + "Initial.txt");
Graph g(in);
return 0;
}
14 changes: 14 additions & 0 deletions rsrc/Initial.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
A B C D E F G H *
A 1 B
B 2 C
C 3 A
C 1 D
D 4 E
E 3 F
F 10 G
G 11 H
H 1 A
A 1 E
A 2 G
B 19 G
B 2 D
93 changes: 93 additions & 0 deletions src/Graph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include "Graph.h"
#include <string>
#include <iterator>
#include <algorithm>
using std::string;
using std::vector;
using std::cout;
using std::endl;

Graph::Graph(std::istream& input)
{
char buffer;

// Get Vertex data
while(input >> buffer && buffer != '*'){
vertexList.push_back(Vertex(buffer));
}
// Get edges and connect
typedef vector<Vertex>::iterator Iter;
Iter tail, head;
size_t weight;

while (!input.eof())
{
// Get edges information
input >> buffer;
tail = std::find(vertexList.begin(), vertexList.end(), Vertex(buffer));

input >> weight;

input >> buffer;
head = std::find(vertexList.begin(), vertexList.end(), Vertex(buffer));

// Add to list
// Link adjacent list
auto tailList_tail{(*tail).firstOut};
auto NewEdge{new Edge(head - vertexList.begin(), tail - vertexList.begin())};
if(tailList_tail){
while(tailList_tail->tailList){
tailList_tail = tailList_tail->tailList;
}
tailList_tail->tailList = NewEdge;
}else{
(*tail).firstOut = NewEdge;
}

// Link de-adjacent list
auto headList_tail{(*head).firstIn};
if(headList_tail){
while(headList_tail->headList){
headList_tail = headList_tail->headList;
}
headList_tail->headList = NewEdge;
}else{
(*head).firstIn = NewEdge;
}
}

// Test
// cout << "Vertex" << "\t" << "Tail" << "\t" << "Head" << endl;
for(auto& i : vertexList){
cout << i.data << "\t";

auto ptr{i.firstIn};
while (ptr){
cout << ptr->headVtx << ' ' << ptr->tailVtx << '\t';
ptr = ptr->tailList;
}
cout << endl;
}
}

Graph::~Graph()
{
for(auto& vtx : vertexList){
// cout<<"Delete: ";
if(!vtx.firstOut) continue;
if(!vtx.firstOut->tailList){
// cout << vtx.firstOut->headVtx <<' '<< vtx.firstOut->tailVtx << '\t';
delete vtx.firstOut;
}else {
auto back{vtx.firstOut}, prior{back->tailList};
while(prior){
// cout << back->headVtx << ' ' << back->tailVtx << '\t';
delete back;
back = prior;
prior = prior->tailList;
}
// cout<< back->headVtx << ' ' << back->tailVtx << endl;
delete back;
}
}
}