来自《大话数据结构》第七章 p274 图
效果
graph 文件
4
5
0 3
1 0
2 0
1 2
2 1
graph.h
#pragma once
#include<vector>
#include<string>
using namespace std;
struct Sidetable{//边表
int from,to;
Sidetable *headlink,*taillink;
Sidetable(int f,int t):from(f),to(t){
headlink=nullptr;
taillink=nullptr;
}
};
struct Vertextable{//顶点表
int data;
Sidetable *firstin,*firstout;
Vertextable(){
firstin=nullptr;
firstout=nullptr;
}
};
class Graph{
int _V,_E; //顶点&变
Vertextable *_adj;//接邻表
public:
Graph(int v);
Graph(const string& filename);
int V() const;
int E() const;
void addEdge(int v,int w);
Vertextable adj(int v);//和v相邻的所有顶点
Vertextable *adj();//单独获取接邻表
string toString();//字符串表示
};
graph.cpp
#include"graph.h"
#include<fstream>
#include<iostream>
Graph::Graph(int v){ //建立固定顶点的图
this->_V=v; //初始化顶点个数
this->_E=0; //初始化边为0
//_adj=new vector<int>[v]; //初始化*
}
Graph::Graph(const string& filename){
//从文件读取V&E,初始化图
fstream f;
f.open(filename,ios::in);
if(!f){
std::cerr<<"can't open file"<<endl;
exit(-1);
}
int V,E;
f>>V>>E;
this->_V=V;
this->_E=E;
_adj=new Vertextable[V]; //新建接邻表
for(int i=0;i<V;i++){
_adj[i].data=i;
}
for(int i=0;i<E;i++){//将每一个边读入
int in_vertex,out_vertex;
f>>in_vertex>>out_vertex;//就按照格式读入
//开始建立十字链表
//1、首先从文件建立一个边
Sidetable *edge=new Sidetable(in_vertex,out_vertex);//初始化一个边
//2、查找这个边的两边端点,在顶点表中查找并且建立联系
//查找这条边的起点,同时查找某个点,添加为“出边”
if(!_adj[in_vertex].firstout){
//如果某个点的出边为nullptr,就可以将这个点的出边指向刚新建的边上
_adj[in_vertex].firstout=edge;
}else{
//如果这个点已经有一条出边了,那么就往后遍历,添加到最后一个节点的headlink上
Sidetable *p=_adj[in_vertex].firstout;
while(p->headlink){
p=p->headlink;
}
p->headlink=edge;
}
//查找这条边的终点,同时查找某个点,添加为“入边”
if(!_adj[out_vertex].firstin){
//如果某个点的入边为nullptr,则可以将这点的入边指向刚新建的边上
_adj[out_vertex].firstin=edge;
}else{
//如果这个点已经有一条入边了,那么就往后遍历,添加到最后一个节点的taillink上
Sidetable *p=_adj[out_vertex].firstin;
while(p->taillink){
p=p->taillink;
}
p->taillink=edge;
}
}
f.close();//关闭文件
}
int Graph::V() const{return _V;}
int Graph::E() const{return _E;}
void Graph::addEdge(int v,int w){
//互相添加边,在vector的头部添加
_E++;
}
Vertextable Graph::adj(int v){ //获取某个顶点的接邻点
return _adj[v];
}
Vertextable* Graph::adj(){ //单独获取接邻表
return _adj;
}
main.cpp
#include<iostream>
#include<cstdio>
#include"graph.h"
using namespace std;
int main(){
Graph g("graph");
cout<<"build success"<<endl;
cout<<"Vertex:"<<g.V()<<endl;
for(int i=0;i<g.V();i++){
printf("[%d] in:",i);
Sidetable *p=g.adj(i).firstin;
while(p){
cout<<p->from<<" ";
p=p->taillink;
}
printf("[%d] out:",i);
p=g.adj(i).firstout;
while(p){
cout<<p->to<<" ";
p=p->headlink;
}
cout<<endl;
}
return 0;
}
CMakeLists.txt
aux_source_directory(. CPP_FILES)
add_executable(out ${CPP_FILES})