나도 궁금 대한 빠른 쓰기 구현 그래프란다 c++에서. 데이터 구조 및 사용할 수 있도록 데릭쉐퍼드와 조작할 수 있는 그래프 알고리즘 (크루스 칼, DFS, BFS 등, 데이크스트라.). 이 경우, 그래서 더욱 간편해지며 알고리즘 구현 데릭쉐퍼드와 올림피아드 기록하십시오 데이터 구조를 좋습니다.
제안하세요 수 등 DS (주) 와 그 무엇이 있을지 구조체 또는 클래스). 가능성이 있는 것으로 알고 있지만, 그러니까 인접 리스트 및 인접행렬 오른길로 주 자세한 코드의 샘플링합니다.
예를 들어 생각해봤죠 우리 섹스한거요 DS 저번에 내가 그래프란다 DFS 를 구현할 수 있다.
struct Edge {
int start;
int end;
struct Edge* nextEdge;
}
하지만 난 이미 DFS 여기있을 그래프화합니다 할 때 쓰는 동안 10 여 개 (line code 반복됩니다.
아래는 데이터 구조에 c++컴파일러는 그래프화합니다 구현 등 인접 리스트.
Stl 의 STL 페어당 나타내는 표현을 사용한 벡터를 정점과 면쪽 및대상 교점까지의.
#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;
struct vertex {
typedef pair<int, vertex*> ve;
vector<ve> adj; //cost of edge, destination vertex
string name;
vertex(string s) : name(s) {}
};
class graph
{
public:
typedef map<string, vertex *> vmap;
vmap work;
void addvertex(const string&);
void addedge(const string& from, const string& to, double cost);
};
void graph::addvertex(const string &name)
{
vmap::iterator itr = work.find(name);
if (itr == work.end())
{
vertex *v;
v = new vertex(name);
work[name] = v;
return;
}
cout << "\nVertex already exists!";
}
void graph::addedge(const string& from, const string& to, double cost)
{
vertex *f = (work.find(from)->second);
vertex *t = (work.find(to)->second);
pair<int, vertex *> edge = make_pair(cost, t);
f->adj.push_back(edge);
}
정말 어떤 알고리즘을 구현하는 데 필요한 달려 없다 은제 탄환 (및 that& # 39, s, t # 39 shouldn& 것은 놀랄 일은 아니다. 일반적인 규칙을 프로그래밍 에로남이네 there& # 39 에 대한 일반 규칙은 없습니다; -).
저는 가끔 다니엘을 노드입니다 / 면쪽 구조를 사용하여 사이트용 다중 그래프 전달됩니까 함께 포인터를 가진다. 좀더 구체적으로 살펴보면 다음과 같습니다.
struct Node
{
... payload ...
Link *first_in, *last_in, *first_out, *last_out;
};
struct Link
{
... payload ...
Node *from, *to;
Link *prev_same_from, *next_same_from,
*prev_same_to, *next_same_to;
};
즉 각 노드는 두 링크됨 규칙수신되는 목록니다 링크와 두 링크됨 목록니다 나가는 링크. '에서' 와 '수' 는 각 노드와 링크 계시나니 동시에 서로 다른 두 개의 두 링크됨 목록: 모든 링크를 통해 목록에 나올 같은 시간에 같은 모든 링크를 목록 및 노드입니다 '에서' 를 '노드입니다.
포인터는 prev_same_from next_same_from '' 와 '에서' 이 나올 때 사용되는 모든 링크를 체인에서의 다음과 같은 노드입니다 , 포인터는 prev_same_to next_same_to '이 아닌' 관리 '와' 때 사용되는 모든 링크를 체인에서의 포인팅 로 같은 노드입니다.
물론 페이로드 크기, 그래프 크기, 그래프 밀도입니다 따라 이 문제를 너무 로버킬링 운행에서어떠한 외곽진입 수 또는 요구하는 메모리 (외에 4 ~ 6 개의 포인터가 가리키는 포인터, ve # 39 는 you& 노드별 호스트당 링크).
비슷한 구조를 전체 구축상의 korea. here.
그러나 몇 가지 이유로 나는 것 같아, t # 39 이 질문은 고대 can& 이해했소 out of my mind.
동시에 모든 솔루션 부문간 그래프, 또한 매우 모든 세부 구현을 제공한다. 이들은 단순히 좋지 않습니다.
따라서 같은 C++ 언어로 그래프화합니다 간결하고 구현될 수 있습니다.
using graph = std::map<int, std::vector<int>>;
또는, 데이터, 추가로 필요한 경우
struct edge {
int nodes[2];
float cost; // add more if you need it
};
using graph = std::map<int, std::vector<edge>>;
이제 아주 잘 꽂으십시오 그래프의 구조에 따라 꽂으십시오 미삭 언어의 진실이며당신이 don& # 39, t 기억해야 할 수 있는 새로운 어설픈 인터페이스입니다 - 이전 어설픈 인터페이스입니다 좋았소 할 것입니다
하지만 나는 또 다른 느낌이 없는 성능을 비교, 이 제안이 왔어요.
NB: 이 'int 의 지수 - 그들은 식별자입니다 않습니다.
인접 리스트 사용하는 이 더 좋아요 의 인덱스 (필터링되지 포인터)
typedef std::vector< Vertex > Vertices;
typedef std::set <int> Neighbours;
struct Vertex {
private:
int data;
public:
Neighbours neighbours;
Vertex( int d ): data(d) {}
Vertex( ): data(-1) {}
bool operator<( const Vertex& ref ) const {
return ( ref.data < data );
}
bool operator==( const Vertex& ref ) const {
return ( ref.data == data );
}
};
class Graph
{
private :
Vertices vertices;
}
void Graph::addEdgeIndices ( int index1, int index2 ) {
vertices[ index1 ].neighbours.insert( index2 );
}
Vertices::iterator Graph::findVertexIndex( int val, bool& res )
{
std::vector<Vertex>::iterator it;
Vertex v(val);
it = std::find( vertices.begin(), vertices.end(), v );
if (it != vertices.end()){
res = true;
return it;
} else {
res = false;
return vertices.end();
}
}
void Graph::addEdge ( int n1, int n2 ) {
bool foundNet1 = false, foundNet2 = false;
Vertices::iterator vit1 = findVertexIndex( n1, foundNet1 );
int node1Index = -1, node2Index = -1;
if ( !foundNet1 ) {
Vertex v1( n1 );
vertices.push_back( v1 );
node1Index = vertices.size() - 1;
} else {
node1Index = vit1 - vertices.begin();
}
Vertices::iterator vit2 = findVertexIndex( n2, foundNet2);
if ( !foundNet2 ) {
Vertex v2( n2 );
vertices.push_back( v2 );
node2Index = vertices.size() - 1;
} else {
node2Index = vit2 - vertices.begin();
}
assert( ( node1Index > -1 ) && ( node1Index < vertices.size()));
assert( ( node2Index > -1 ) && ( node2Index < vertices.size()));
addEdgeIndices( node1Index, node2Index );
}
짝수 간단해진다는 표현 할 수 있을 것으로 보고 있을 수 없는 그래프 알고리즘 포락선으로 사용할 수 있는 사람이 다른 테스트 (그래프). 이는 다음과 같이 인접 관계, 그 정점을 맵으로 열거합니다 에서 -
#include<bits/stdc++.h>
using namespace std;
/* implement the graph as a map from the integer index as a key to the adjacency list
* of the graph implemented as a vector being the value of each individual key. The
* program will be given a matrix of numbers, the first element of each row will
* represent the head of the adjacency list and the rest of the elements will be the
* list of that element in the graph.
*/
typedef map<int, vector<int> > graphType;
int main(){
graphType graph;
int vertices = 0;
cout << "Please enter the number of vertices in the graph :- " << endl;
cin >> vertices;
if(vertices <= 0){
cout << "The number of vertices in the graph can't be less than or equal to 0." << endl;
exit(0);
}
cout << "Please enter the elements of the graph, as an adjacency list, one row after another. " << endl;
for(int i = 0; i <= vertices; i++){
vector<int> adjList; //the vector corresponding to the adjacency list of each vertex
int key = -1, listValue = -1;
string listString;
getline(cin, listString);
if(i != 0){
istringstream iss(listString);
iss >> key;
iss >> listValue;
if(listValue != -1){
adjList.push_back(listValue);
for(; iss >> listValue; ){
adjList.push_back(listValue);
}
graph.insert(graphType::value_type(key, adjList));
}
else
graph.insert(graphType::value_type(key, adjList));
}
}
//print the elements of the graph
cout << "The graph that you entered :- " << endl;
for(graphType::const_iterator iterator = graph.begin(); iterator != graph.end(); ++iterator){
cout << "Key : " << iterator->first << ", values : ";
vector<int>::const_iterator vectBegIter = iterator->second.begin();
vector<int>::const_iterator vectEndIter = iterator->second.end();
for(; vectBegIter != vectEndIter; ++vectBegIter){
cout << *(vectBegIter) << ", ";
}
cout << endl;
}
}
이것은 기본적인 구현 그래프란다. 참고: 내가 사용하는 교점까지의 원하는거요 체인된 내년 교점까지의. 및 각 가리키는 바뀌엇어요 교점까지의 는 인접한 노드입니다.
#include <iostream>
using namespace std;
// 1 ->2
// 1->4
// 2 ->3
// 4->3
// 4 -> 5
// Adjacency list
// 1->2->3-null
// 2->3->null
//4->5->null;
// Structure of a vertex
struct vertex {
int i;
struct node *list;
struct vertex *next;
};
typedef struct vertex * VPTR;
// Struct of adjacency list
struct node {
struct vertex * n;
struct node *next;
};
typedef struct node * NODEPTR;
class Graph {
public:
// list of nodes chained together
VPTR V;
Graph() {
V = NULL;
}
void addEdge(int, int);
VPTR addVertex(int);
VPTR existVertex(int i);
void listVertex();
};
// If vertex exist, it returns its pointer else returns NULL
VPTR Graph::existVertex(int i) {
VPTR temp = V;
while(temp != NULL) {
if(temp->i == i) {
return temp;
}
temp = temp->next;
}
return NULL;
}
// Add a new vertex to the end of the vertex list
VPTR Graph::addVertex(int i) {
VPTR temp = new(struct vertex);
temp->list = NULL;
temp->i = i;
temp->next = NULL;
VPTR *curr = &V;
while(*curr) {
curr = &(*curr)->next;
}
*curr = temp;
return temp;
}
// Add a node from vertex i to j.
// first check if i and j exists. If not first add the vertex
// and then add entry of j into adjacency list of i
void Graph::addEdge(int i, int j) {
VPTR v_i = existVertex(i);
VPTR v_j = existVertex(j);
if(v_i == NULL) {
v_i = addVertex(i);
}
if(v_j == NULL) {
v_j = addVertex(j);
}
NODEPTR *temp = &(v_i->list);
while(*temp) {
temp = &(*temp)->next;
}
*temp = new(struct node);
(*temp)->n = v_j;
(*temp)->next = NULL;
}
// List all the vertex.
void Graph::listVertex() {
VPTR temp = V;
while(temp) {
cout <<temp->i <<" ";
temp = temp->next;
}
cout <<"\n";
}
// Client program
int main() {
Graph G;
G.addEdge(1, 2);
G.listVertex();
}
위의 코드는 확장하십시오 DFS 함께 할 수 있습니다 / BFS 상술합니다.