@CrazyHenry
2018-03-26T12:55:40.000000Z
字数 4788
阅读 1202
dddd数据结构课本
- Author:李英民 | Henry
- E-mail: li
_yingmin@outlookdotcom- Home: https://liyingmin.wixsite.com/henry
快速了解我: About Me
转载请保留上述引用内容,谢谢配合!
#include <iostream>#include <cassert>using namespace std;// 边template<typename Weight>class Edge{private:int a,b; // 边的两个端点Weight weight; // 边的权值public:// 构造函数Edge(int a, int b, Weight weight){this->a = a;this->b = b;this->weight = weight;}// 空的构造函数, 所有的成员变量都取默认值Edge(){}~Edge(){}int v(){ return a;} // 返回第一个顶点int w(){ return b;} // 返回第二个顶点Weight wt(){ return weight;} // 返回权值// 给定一个顶点, 返回另一个顶点int other(int x){assert( x == a || x == b );return x == a ? b : a;}// 输出边的信息friend ostream& operator<<(ostream &os, const Edge &e){os<<e.a<<"-"<<e.b<<": "<<e.weight;return os;}// 边的大小比较, 是对边的权值的大小比较bool operator<(Edge<Weight>& e){return weight < e.wt();}bool operator<=(Edge<Weight>& e){return weight <= e.wt();}bool operator>(Edge<Weight>& e){return weight > e.wt();}bool operator>=(Edge<Weight>& e){return weight >= e.wt();}bool operator==(Edge<Weight>& e){return weight == e.wt();}};
#include <iostream>#include <string>#include <fstream>#include <sstream>#include <cassert>using namespace std;// 读取有权图template <typename Graph, typename Weight>class ReadGraph{public:// 从文件filename中读取有权图的信息, 存储进图graph中ReadGraph(Graph &graph, const string &filename){ifstream file(filename);string line;int V, E;assert(file.is_open());// 第一行读取图中的节点个数和边的个数assert( getline(file,line));stringstream ss(line);ss >> V >> E;assert( graph.V() == V );// 读取每一条边的信息for( int i = 0 ; i < E ; i ++ ){assert( getline(file,line));stringstream ss(line);int a, b;Weight w;ss>>a>>b>>w;assert( a >= 0 && a < V );assert( b >= 0 && b < V );graph.addEdge(a, b, w);}}};
#include <iostream>#include <vector>#include <cassert>#include "Edge.h"using namespace std;// 稠密图 - 邻接矩阵template <typename Weight>class DenseGraph{private:int n, m; // 节点数和边数bool directed; // 是否为有向图vector<vector<Edge<Weight> *>> g; // 图的具体数据public:// 构造函数DenseGraph( int n , bool directed){assert( n >= 0 );this->n = n;this->m = 0;this->directed = directed;// g初始化为n*n的矩阵, 每一个g[i][j]指向一个边的信息, 初始化为NULLg = vector<vector<Edge<Weight> *>>(n, vector<Edge<Weight> *>(n, NULL));}// 析构函数~DenseGraph(){for( int i = 0 ; i < n ; i ++ )for( int j = 0 ; j < n ; j ++ )if( g[i][j] != NULL )delete g[i][j];}int V(){ return n;} // 返回节点个数int E(){ return m;} // 返回边的个数// 向图中添加一个边, 权值为weightvoid addEdge( int v, int w , Weight weight ){assert( v >= 0 && v < n );assert( w >= 0 && w < n );// 如果从v到w已经有边, 删除这条边if( hasEdge( v , w ) ){delete g[v][w];if( v != w && !directed )delete g[w][v];m --;}g[v][w] = new Edge<Weight>(v, w, weight);if( v != w && !directed )g[w][v] = new Edge<Weight>(w, v, weight);m ++;}// 验证图中是否有从v到w的边bool hasEdge( int v , int w ){assert( v >= 0 && v < n );assert( w >= 0 && w < n );return g[v][w] != NULL;}// 显示图的信息void show(){for( int i = 0 ; i < n ; i ++ ){for( int j = 0 ; j < n ; j ++ )if( g[i][j] )cout<<g[i][j]->wt()<<"\t";elsecout<<"NULL\t";cout<<endl;}}// 邻边迭代器, 传入一个图和一个顶点,// 迭代在这个图中和这个顶点向连的所有边class adjIterator{private:DenseGraph &G; // 图G的引用int v;int index;public:// 构造函数adjIterator(DenseGraph &graph, int v): G(graph){this->v = v;this->index = -1; // 索引从-1开始, 因为每次遍历都需要调用一次next()}~adjIterator(){}// 返回图G中与顶点v相连接的第一个边Edge<Weight>* begin(){// 索引从-1开始, 因为每次遍历都需要调用一次next()index = -1;return next();}// 返回图G中与顶点v相连接的下一个边Edge<Weight>* next(){// 从当前index开始向后搜索, 直到找到一个g[v][index]为truefor( index += 1 ; index < G.V() ; index ++ )if( G.g[v][index] )return G.g[v][index];// 若没有顶点和v相连接, 则返回NULLreturn NULL;}// 查看是否已经迭代完了图G中与顶点v相连接的所有边bool end(){return index >= G.V();}};};
#include <iostream>#include <vector>#include <cassert>#include "Edge.h"using namespace std;// 稀疏图 - 邻接表template<typename Weight>class SparseGraph{private:int n, m; // 节点数和边数bool directed; // 是否为有向图vector<vector<Edge<Weight> *> > g; // 图的具体数据public:// 构造函数SparseGraph( int n , bool directed){assert(n >= 0);this->n = n;this->m = 0; // 初始化没有任何边this->directed = directed;// g初始化为n个空的vector, 表示每一个g[i]都为空, 即没有任和边g = vector<vector<Edge<Weight> *> >(n, vector<Edge<Weight> *>());}// 析构函数~SparseGraph(){for( int i = 0 ; i < n ; i ++ )for( int j = 0 ; j < g[i].size() ; j ++ )delete g[i][j];}int V(){ return n;} // 返回节点个数int E(){ return m;} // 返回边的个数// 向图中添加一个边, 权值为weightvoid addEdge( int v, int w , Weight weight){assert( v >= 0 && v < n );assert( w >= 0 && w < n );// 注意, 由于在邻接表的情况, 查找是否有重边需要遍历整个链表// 我们的程序允许重边的出现g[v].push_back(new Edge<Weight>(v, w, weight));if( v != w && !directed )g[w].push_back(new Edge<Weight>(w, v, weight));m ++;}// 验证图中是否有从v到w的边bool hasEdge( int v , int w ){assert( v >= 0 && v < n );assert( w >= 0 && w < n );for( int i = 0 ; i < g[v].size() ; i ++ )if( g[v][i]->other(v) == w )return true;return false;}// 显示图的信息void show(){for( int i = 0 ; i < n ; i ++ ){cout<<"vertex "<<i<<":\t";for( int j = 0 ; j < g[i].size() ; j ++ )cout<<"( to:"<<g[i][j]->w()<<",wt:"<<g[i][j]->wt()<<")\t";cout<<endl;}}// 邻边迭代器, 传入一个图和一个顶点,// 迭代在这个图中和这个顶点向连的所有边class adjIterator{private:SparseGraph &G; // 图G的引用int v;int index;public:// 构造函数adjIterator(SparseGraph &graph, int v): G(graph){this->v = v;this->index = 0;}~adjIterator(){}// 返回图G中与顶点v相连接的第一个边Edge<Weight>* begin(){index = 0;if( G.g[v].size() )return G.g[v][index];// 若没有顶点和v相连接, 则返回NULLreturn NULL;}// 返回图G中与顶点v相连接的下一个边Edge<Weight>* next(){index += 1;if( index < G.g[v].size() )return G.g[v][index];return NULL;}// 查看是否已经迭代完了图G中与顶点v相连接的所有顶点bool end(){return index >= G.g[v].size();}};};