I am afraid that the graph application isC ++All data structures are the most extensive, but it is doomed that there is nothing to talk about when talking about "data structure graphs"-the most important thing about graphs is algorithms, in addition, a considerable number of them are very professional, and generally people will not be able to access them. Relatively speaking, the structure is very lightweight. You can see that there are very few operations on the elements in the graph, far from the list of "interfaces" listed in a single-chain table ". -- If a structure is complex, operations that can be defined exactly are limited.
I will introduce the graph application in detail from the following aspects: basic storage method, DFS and BFS, undirected graph, Minimum Spanning Tree, shortest path, and active network (AOV and AOE. This is the first article in this series. It mainly introduces the basic storage methods of graphs.
Basic Storage Method
In any case, you must first save the image. Do not list many methods on the books. There is only one-the adjacent matrix. If the matrix is sparse, you can use the cross-linked list to store the matrix (see the sparse matrix of C ++ Data Structure Learning ). If we only relate to the relationship of rows, It is the adjacent table (the out-of-edge table). On the contrary, we only care about the relationship between columns, that is, the inverse adjacent table (The in-edge table ).
The following two storage methods are provided.
- # Ifndef Graphmem_H
- # Define Graphmem_H
-
- # Include
- # Include
- Using NamespaceStd;
-
- Template<ClassName,ClassDist,ClassMem>ClassNetwork;
-
- Const IntMaxV = 20;// Maximum number of nodes
- Template<ClassName,ClassDist>
- ClassAdjMatrix
- {
- Friend ClassNetwork >;
- Public:
- AdjMatrix (): vNum (0), eNum (0)
- {
- Vertex =NewName [maxV]; edge =NewDist * [maxV];
- For(IntI = 0; I <maxV; I ++) edge [I] =NewDist [maxV];
- }
- ~ AdjMatrix ()
- {
- For(IntI = 0; I <maxV; I ++)Delete[] Edge [I];
- Delete[] Edge;Delete[] Vertex;
- }
- BoolInsertV (name v)
- {
- If(Find (v ))Return False;
- Vertex [vNum] = v;
- For(IntI = 0; I <maxV; I ++) edge [vNum] [I] = NoEdge;
- VNum ++;Return True;
- }
- BoolInsertE (name v1, name v2, dist cost)
- {
- IntI, j;
- If(V1 = v2 |! Find (v1, I) |! Find (v2, j ))Return False;
- If(Edge [I] [j]! = NoEdge)Return False;
- Edge [I] [j] = cost; eNum ++;Return True;
- }
- Name & getV (IntN ){ReturnVertex [n];}// No cross-border check
- IntNextV (IntM,IntN)// Returns the first adjacent vertex after vertex n of vertex m.-1 is not returned.
- {
- For(IntI = n + 1; I <vNum; I ++)If(Edge [m] [I]! = NoEdge)ReturnI;
- Return-1;
- }
- Private:
- IntVNum, eNum;
- Dist NoEdge, ** edge; name * vertex;
- BoolFind (ConstName & v)
- {
- For(IntI = 0; I <vNum; I ++)If(V = vertex [I])Return True;
- Return False;
- }
- BoolFind (ConstName & v,Int& I)
- {
- For(I = 0; I <vNum; I ++)If(V = vertex [I])Return True;
- Return False;
- }
- };
-
- Template<ClassName,ClassDist>
- ClassShortlist
- {
- Friend ClassNetwork >;
- Public:
- Partition list (): vNum (0), eNum (0 ){}
- ~ Partition list ()
- {
- For(IntI = 0; I <vNum; I ++)DeleteVertices [I]. e;
- }
- BoolInsertV (name v)
- {
- If(Find (v ))Return False;
- Vertices. push_back (vertex (v,NewList ));
- VNum ++;Return True;
- }
- BoolInsertE (ConstName & v1,ConstName & v2,ConstDist & cost)
- {
- IntI, j;
- If(V1 = v2 |! Find (v1, I) |! Find (v2, j ))Return False;
- For(List : Iterator iter = vertices [I]. e-> begin ();
- Iter! = Vertices [I]. e-> end () & iter-> vID <j; iter ++ );
- If(Iter = vertices [I]. e-> end ())
- {
- Vertices [I]. e-> push_back (edge (j, cost); eNum ++;Return True;
- }
- If(Iter-> vID = j)Return False;
- Vertices [I]. e-> insert (iter, edge (j, cost); eNum ++;Return True;
- }
- Name & getV (IntN ){ReturnVertices [n]. v ;}// No cross-border check
- IntNextV (IntM,IntN)// Returns the first adjacent vertex after vertex n of vertex m.-1 is not returned.
- {
- For(List : Iterator iter = vertices [m]. e-> begin ();
- Iter! = Vertices [m]. e-> end (); iter ++)If(Iter-> vID> n)ReturnIter-> vID;
- Return-1;
- }
-
- Private:
- BoolFind (ConstName & v)
- {
- For(IntI = 0; I <vNum; I ++)If(V = vertices [I]. v)Return True;
- Return False;
- }
- BoolFind (ConstName & v,Int& I)
- {
- For(I = 0; I <vNum; I ++)If(V = vertices [I]. v)Return True;
- Return False;
- }
- StructEdge
- {
- Edge (){}
- Edge (IntVID, dist cost): vID (vID), cost (cost ){}
- IntVID;
- Dist cost;
- };
- StructVertex
- {
- Vertex (){}
- Vertex (name v, list * E): v (v), e (e ){}
- Name v;
- List * E;
- };
- IntVNum, eNum;
- Vector Vertices;
- };
-
- # Endif
This implementation is very simple, but it should be able to meet the requirements described later. There is nothing to do now. Don't worry. In the next article, we will describe the DFS and BFS of the graph.
- Classical 4-lecture C ++ sorting
- Common c ++ programming tools
- 50 tips for C ++ beginners
- The 20 most basic rules of c ++
- Programmers must read the summary of c ++ pen questions