数据结构中,我们存储图结构主要有5种方式:邻接矩阵、邻接表、十字链表、邻接多重表、边集数组。在算法竞赛中,我们用比较多是前两种,但由于邻接矩阵操作起来的时间复杂度和空间复杂度较高(如果存储稀疏图会极大浪费空间),因此我们更多采用邻接表进行存储,为了避免复杂的指针操作,在这里我们使用链式前向星进行存储。
graph.h
#pragma once
#include <iostream>
#include <vector>
using namespace std;
struct node{ //边集
int to; //指向的结点
int wt; //该结点与所指向的结点的权值
int next; //下一结点
node() { to = 0; wt = 0; next = -1; }
node(int t, int w, int n): to(t),wt(w),next(n){}
};
class Graph{
private:
vector<int> head; //顶点集,head[i]表示顶点i所指向的边集edge的下标
vector<node> edge; //边集
int nodeNum; //顶点的数目
int edgeNum; //边的数目
bool isDirected; //该图是有向图还是无向图
vector<int> isvisited;
bool visited();
void dfs_searching(int startIndex);
void initVis();
public:
Graph(int n,bool isDirected); //顶点数,是否为有向图
void addEdge(int u, int v, int w); //在顶点u和v之间加一条权值为w的边
void printEdgeTable(); //打印出邻接表
void dfs(int startIndex); //dfs搜索图的各结点
};
graph.cpp
#include "graph.h"
bool Graph::visited(){
for (int i = 1; i <= nodeNum; i++) {
if (isvisited[i] == 0) {
return 0;
}
}
return 1;
}
void Graph::dfs_searching(int startIndex){ //dfs搜索
if (!isvisited[startIndex]) {
isvisited[startIndex] = 1;
cout << startIndex << ' ';
int cur = head[startIndex];
while (cur != -1) {
dfs_searching(edge[cur].to);
cur = edge[cur].next;
}
}
}
void Graph::initVis(){
for (int i = 1; i <= nodeNum; i++) {
isvisited[i] = 0;
}
}
Graph::Graph(int n,bool isDirected){
if (n <= 0) {
return;
}
head.resize(n + 1, -1);
nodeNum = n;
edgeNum = edge.size();
this->isDirected = isDirected;
isvisited.resize(n + 1, 0);
}
void Graph::addEdge(int u, int v, int w){
if (u > nodeNum || v > nodeNum) {
return;
}
//采用类似 链表的“头插法” 插入节点
edge.push_back(node(v,w,head[u]));
head[u] = edge.size() - 1;
if (!isDirected) { //如果是无向图
edge.push_back(node(u, w, head[v]));
head[v] = edge.size() - 1;
}
edgeNum++;
}
void Graph::printEdgeTable(){
cout << "head\tedge\n";
for (int i = 1; i <= nodeNum; i++) {
cout << i << ":\t";
int cur = head[i];
while (cur != -1) {
cout << "[" << edge[cur].to << ' ' << edge[cur].wt << "]\t";
cur = edge[cur].next;
}
cout << endl;
}
}
void Graph::dfs(int startIndex){
dfs_searching(startIndex);
initVis();
}
main.cpp
#include "graph.h"
void test() {
int n, m;
cin >> n >> m; //n为顶点数,m为边数
Graph g(n, 0);
for (int i = 1; i <= m; i++) {
int u, v, w;
cin >> u >> v >> w;
g.addEdge(u, v, w);
}
g.printEdgeTable();
cout << endl;
g.dfs(1); //从顶点1开始dfs
}
int main() {
test();
return 0;
}
1987

被折叠的 条评论
为什么被折叠?



