图的存储:邻接矩阵和邻接表(C++)

一、临界矩阵

1.示例效果

无向图:   

       

 

有向网:       

 

 2. 代码

 1 #include <iostream>
 2 #include <unordered_map>
 3 #include <vector>
 4 #include <string>
 5 //storage graph by adjacency matrix
 6 using std::unordered_map;
 7 using std::vector;
 8 using std::string;
 9 enum graphType { UG, DG,UN,DN };          //无向图,有向图,无向网,有向网
10 class Graph{
11 public:
12     unordered_map<string,int> vertex2index;   //顶点的名字 ==》下标
13     vector<vector<int>> edjes;                //存储边的二维数组
14     int n, e;                                 //顶点数和边数
15     enum graphType type;                      //图的类型
16     Graph(int vNum=1,int eNum=0,enum graphType t=UG):
17         n(vNum),e(eNum),type(t){}
18     Graph* createGraph();
19     
20     void showGraph() {
21         std::cout << "开始显示图:\n";
22         auto ite = vertex2index.begin();
23         //打印节点名字横
24         std::cout << "    ";
25         for (; ite!=vertex2index.end(); ite++) {
26             std::cout<<(*ite).first << "  ";
27         }
28         std::cout << "\n";
29         //打印节点
30         ite = vertex2index.begin();
31         for (int i = 0; i < n; i++) {
32             //打印节点名字竖
33             std::cout << (*ite++).first << "  ";
34             for (int j = 0; j < n; j++) {
35                 //是默认填充则打印#,否则打印其权值
36                 edjes[i][j] == INT_MAX ? std::cout << "#   " : std::cout << edjes[i][j] << "   ";
37             }
38             std::cout << "\n";
39         }
40     }
41 };
42 Graph* Graph::createGraph()
43 {
44     std::cout << "图的信息:\n顶点数:" << n << "  边数:" << e<<"  类型:";
45     switch (type) {
46     case UG:std::cout << "无向图\n"; break;
47     case DG:std::cout << "有向图\n"; break;
48     case UN:std::cout << "无向网\n"; break;
49     case DN:std::cout << "有向网\n"; break;
50     }
51     //根据顶点数来构造矩阵, 无边填充INT_MAX
52     for (int i = 0; i < n; i++) {
53         vector<int> temp(n, INT_MAX);
54         edjes.emplace_back(temp);
55     }
56     //填充顶点数组,确立顶点名字和下标的映射
57     for (int i = 0; i < n; i++) {
58         string name;
59         std::cout << "输入第" << i + 1 << "个顶点的名字(string):";
60         std::cin >> name;
61         vertex2index[name] = i;
62     }
63     //输入边的信息
64     for (int i = 0; i < e; i++) {
65         string n1, n2;
66         int pow = 1, row = 0, column = 0;
67         std::cout << "输入第" << i + 1;
68         if (type == UG || type == DG) {                            //UG或DG没有权值,默认显示为1
69             std::cout << "条边的弧头,弧尾:\n";
70             std::cin >> n1 >> n2;
71         }
72         else {
73             std::cout <<"条边的弧头,弧尾,权值:\n";                //UN或DN有权值
74             std::cin >> n1 >> n2 >> pow;
75         }
76         row = vertex2index[n1]; column = vertex2index[n2];        //根据边的名字找到对应下标
77         edjes[row][column] = pow;
78         type == UG || type == UN ?edjes[column][row] = pow : 1;   //如果是UG或UN则对角线对称
79     }
80     
81     return this;
82 }
83 int main()
84 {
85     //示例:6节点10边有向网
86     Graph *g = new Graph(6,10,DN);
87     g->createGraph();
88     g->showGraph();
89     std::cin.get();
90 }

 二、邻接表

1. 示例效果

 

 

 2. 代码

 1 // 头文件同上   
 2 //edgeNode边节点
 3 struct edgeNode {    
 4     int index;                      //这条边弧尾节点的下标
 5     edgeNode* next;                   //指向下一条边
 6     int weight;                     //这条边的权重;图的weight默认都表示为1
 7     edgeNode(int n,int w=1):index(n),next(),weight(w){}
 8 };
 9 //vertex 顶点节点
10 struct vertexNode {    
11     string data;                        //顶点的名字或数据
12     edgeNode* next;                   //顶点节点的指针域指向边节点
13     vertexNode(string str):data(str),next(){}
14 };
15 class AdjList {
16     vector<vertexNode*> adjList;            //邻接表
17     int n, e;                               //顶点的个数,边的个数
18     enum graphType type;                    //图的类型
19     unordered_map<string, int> vertex2index;      //顶点的名字 ==》下标的映射
20 public:
21     AdjList(int verNum=1,int edgNum=0,enum graphType t=UG):
22         n(verNum),e(edgNum),type(t){}
23     void createGraph() {
24         std::cout << "图的信息:\n顶点数:" << n << "  边数:" << e << "  类型:";
25         switch (type) {
26         case UG:std::cout << "无向图\n"; break;
27         case DG:std::cout << "有向图\n"; break;
28         case UN:std::cout << "无向网\n"; break;
29         case DN:std::cout << "有向网\n"; break;
30         }
31         for (int i = 0; i < n; i++) {
32             std::cout << "请输入第" << i+1 << "个顶点的数据(名字string):";
33             string str; std::cin >> str;
34             adjList.push_back(new vertexNode(str));
35             vertex2index[str] = i;
36         }
37         string s1, s2;
38         for (int i = 0; i < e; i++) {
39             std::cout << "输入第" << i + 1;
40             if (type == UG || type == DG) {                      //UG或DG没有权值,默认显示为1
41                 std::cout << "条边的弧头,弧尾:\n";
42                 std::cin >> s1 >> s2;
43                 int n1 = vertex2index[s1], n2 = vertex2index[s2];
44                 edgeNode *node = new edgeNode(n2);
45                 //把边节点挂上去
46                 node->next = adjList[n1]->next;
47                 adjList[n1]->next = node;
48             }
49             else {
50                 int weight = 1;
51                 std::cout << "条边的弧头,弧尾,权值:\n";            //UN或DN有权值
52                 std::cin >> s1 >> s2 >> weight;
53                 int n1 = vertex2index[s1], n2 = vertex2index[s2];
54                 edgeNode *node = new edgeNode(n2, weight);
55                 //把边节点挂上去
56                 node->next = adjList[n1]->next;
57                 adjList[n1]->next = node;
58             }
59         }
60     }
61     void showGraph() {
62         std::cout << "开始显示图:\n";
63         for (auto& i: adjList) {
64             std::cout << i->data << "->";
65             edgeNode *cur = i->next;
66             while (cur) {
67                 std::cout <<"("<< cur->index <<","<<cur->weight<<")"<< "->";
68                 cur = cur->next;
69             }
70             std::cout << "null";
71             std::cout << "\n";
72         }
73     }
74 };
75 
76 int main()
77 {
78     //示例:4节点5边有向网
79     AdjList *g = new AdjList(5,6,DN);
80     g->createGraph();
81     g->showGraph();
82     std::cin.get();
83     std::cin.get();
84 }

 

posted @ 2021-12-27 13:09  jiaminw  阅读(509)  评论(0编辑  收藏  举报