图----邻接表
来源:互联网 发布:跟知乎类似的网站 编辑:程序博客网 时间:2024/06/13 21:09
无向图的实现
要求:基于邻接表实现图的ADT,以及图的各种基本操作。
一、邻接表
数组与指针结合的存储方式。
1.图中的每一个顶点一维数组存储,在顶点数组中还需有指向第一个邻接点的指针。
2.图中每个顶点和他的所有的邻接点构成一个线性表。
如下图即为一个无向图的邻接表表示法:
就上图建立一个邻接表。
1)建立一个一维数组储存顶点值。
1)有多少个顶点就要建立多少条单链表。本图需要建立4条单链表。注:每个单链表的第一个元素即为该顶点本身。
V0->v1->v2->v3
v1->v0->v2
v2->v0->v1->v3
v3->v0->v2
2)在实际中存储的单链表应为每个顶点元素在数组中的下标。
带权值的有向图:
二、数据结构
1.顶点类ADT
template <typename E> class Link {public: E element; // Value for this node Link *next; // Pointer to next node in list // Constructors Link(const E& elemval, Link* nextval =NULL) { element = elemval; next = nextval; } Link(Link* nextval =NULL) { next = nextval; }};
2、单链表类
template <typename E> class List { // List ADTprivate: void operator =(const List&) {} // Protect assignment List(const List&) {} // Protect copy constructorpublic: List() {} // Default constructor virtual ~List() {} // Base destructor // Clear contents from the list, to make it empty. virtual void clear() = 0; // Insert an element at the current location. // item: The element to be inserted virtual void insert(const E& item) = 0; // Append an element at the end of the list. // item: The element to be appended. virtual void append(const E& item) = 0; // Remove and return the current element. // Return: the element that was removed. virtual E remove() = 0; // Set the current position to the start of the list virtual void moveToStart() = 0; // Set the current position to the end of the list virtual void moveToEnd() = 0; // Move the current position one step left. No change // if already at beginning. virtual void prev() = 0; // Move the current position one step right. No change // if already at end. virtual void next() = 0; // Return: The number of elements in the list. virtual int length() const = 0; // Return: The position of the current element. virtual int currPos() const = 0; // Set current position. // pos: The position to make current. virtual void moveToPos(int pos) = 0; // Return: The current element. virtual const E& getValue() const = 0;};
3、图ADT
#ifndef GRAPH#define GRAPHtemplate <typename VertexType>class Graph {private: void operator =(const Graph&) {} // Protect assignment Graph(const Graph&) {} // Protect copy constructorpublic: Graph() {} // Default constructor virtual ~Graph() {} // Base destructor // Initialize a graph of n vertices virtual void Init(int n) =0; // Return: the number of vertices and edges virtual int n() =0; virtual int e() =0; // Return v's first neighbor virtual int first(int v) =0; // Return v's next neighbor virtual int next(int v, int w) =0; //设置图的类型(有向图或无向图) virtual void setType(bool flag)=0; //获取图的类型 virtual bool getType()=0; //找到(包含实际信息的)顶点在图中的位置 virtual int locateVex(VertexType u) =0; //返回某个顶点的值(实际信息) virtual VertexType getVex(int v)=0; //给某个顶点赋值 virtual void putVex(int v,VertexType value) =0; // Set the weight for an edge virtual void setEdge(int v1, int v2, int wght) =0; // Delete an edge virtual void delEdge(int v1, int v2) =0; // Determine if an edge is in the graph virtual bool isEdge(int i, int j) =0; // Return an edge's weight virtual int weight(int v1, int v2) =0; // Get and Set the mark value for a vertex virtual int getMark(int v) =0; virtual void setMark(int v, int val) =0;};#endif
三、构造图
char* getl(char* buffer, int n, FILE* fid) { char* ptr; ptr = fgets(buffer, n, fid); while ((ptr != NULL) && (buffer[0] == '#')) ptr = fgets(buffer, n, fid); return ptr;}/*构建图*/ //template <typename GType>Graph<string>* createGraph( FILE* fid) { char buffer[LINELEN+1]; // Line buffer for reading int i, v1, v2, dist; /*【读取顶点个数】 */ if (getl(buffer, LINELEN, fid) == NULL) // Unable to get number of vertices { cout << "Unable to read number of vertices\n"; return NULL; } int num=atoi(buffer); /*【建图初始化】 */ Graph<string>* G = new Graphl<string>(num); /*【读取图的顶点信息并存储】 */ if (getl(buffer, LINELEN, fid) == NULL) // Unable to get graph type { cout << "Unable to read info of vertices\n"; return NULL ; } char* cbuff=buffer; string ver=strtok(cbuff," ");//空格分割各顶点信息 //存储前n-1个 for(i=0;i<num-1;i++){ G->putVex(i,ver);//存储顶点信息 ver=strtok(NULL," "); } //最后一个顶点信息之后的字符可能是\t之类的字符故不能和上面一样 //直接用空格分割 int k=0; while(ver[k]>=33&&ver[k]<=126){ k++; } ver=ver.substr(0,k);//获取最后一个顶点信息 G->putVex(i,ver);//存储顶点信息 /*【读取图的类型】 */ if (getl(buffer, LINELEN, fid) == NULL) // Unable to get graph type { cout << "Unable to read graph type\n"; return NULL ; } if (buffer[0] == 'U')//无向图 G->setType(true);//undirected = true; else if (buffer[0] == 'D')//有向图 G->setType(false);//undirected = false; else { cout << "Bad graph type: |" << buffer << "|\n"; return NULL; } /*【读取边数和边】 */ if (getl(buffer, LINELEN, fid) == NULL) // Unable to get graph type { cout << "Unable to read num of edges\n"; return NULL ; } int num_edge=atoi(buffer); for(int m=0;m<num_edge;m++){ getl(buffer, LINELEN, fid); string sbuff=buffer; string tvalue; int loc1=sbuff.find(' ');//找到第一个分割空格的位置 tvalue=sbuff.substr(0,loc1);//读取第一个顶点信息到tvalue //cout<<"第一个顶点" <<tvalue<<endl;//////////// //找到第一个顶点在图中的位置 v1 = G->locateVex(tvalue); int loc2=sbuff.find(' ',loc1+1);//找第二个分割空格的位置 tvalue=sbuff.substr(loc1+1,loc2-loc1-1);//读取第二个顶点信息到tvalue //cout<<"第二个顶点" <<tvalue<<endl;//////////// //找到第二个顶点在图中的位置 v2 = G->locateVex(tvalue); //获取dist边权值 i=loc2+1; dist=atoi(&buffer[i]); //cout<<"dist="<<dist<<endl; //存储边 G->setEdge(v1,v2,dist); } return G;}
最后:我只是一只勤劳的搬运工,感谢学长学姐的源码,还有。。。。http://blog.csdn.net/jnu_simba/article/details/8866844
阅读全文
0 0
- 图的邻接表
- 图的邻接表
- 图的邻接表
- c++ 图(邻接表)
- 图 邻接表
- 图的邻接表
- 图-----邻接表
- 图 邻接矩阵 邻接表
- 图的邻接表
- 邻接表与图
- 图(邻接表)
- 邻接表创建图
- 图的邻接表
- 图的邻接表
- 邻接表保存图
- 图的邻接表
- 图之邻接表
- 图 - 邻接表
- JavaScript floor() 方法
- 史上最全!阿里智能人机交互的核心技术解析
- 阿里云企业邮箱使用nodemailer,使用nodemailer发送错误信息
- 菜单跳转高亮问题
- 条款05:了解C++默默编写并调用那些函数
- 图----邻接表
- 世界信息产业的第三次浪潮:物联网,物物联网
- PASCAL VOC数据集分析(检测部分)
- python矩阵
- 硬盘无法拷贝大于4G的文件,和百度云盘4G限制的一些解决办法
- 阿里云--Python使用flask开发项目,外网无法访问
- mybatis的自动生成插件
- 移动工程师如何学习人工智能
- 数据控制—完整性约束