相比 邻接表LINk
完善数据结构:结点名字ElemType
上图:
上码:
1 // vs 2015
2 // 邻接表 无向不带权
3
4
5 #include
6 #include
7
8 using namespace std;
9 #define MAX 10
10
11 typedef int ElemType; //结点被标记的类型
12 //弧结点
13 typedef struct ArcNode {
14 ElemType name; //与顶点相连的弧name
15 struct ArcNode *next; //下一个兄弟弧
16 } ArcNode;
17 //顶点信息
18 typedef struct VNode {
19 ElemType name; //顶点被标记名字
20 ArcNode * firstarc; //顶点连接的第一条弧(左右不敏感)
21 } VNode, AdjList[MAX];
22 //邻接表
23 typedef struct {
24 AdjList vertinfo; //hash表
25 int vexnum; //顶点数
26 int arcnum; //弧数
27 } AdjGraph;
28
29
30 int visited[MAX];
31 void dfs_byecursion(AdjGraph G, ElemType stapos)
32 {
33 //-------增强健壮性,主要检测第一个stapos是否在图中------
34
35 bool isIn = false; //判断stapos结点是否在图中
36 int pos = 0; //记录结点在vertinfo中的索引
37 for (int i = 0; i < G.vexnum; i++)
38 if (stapos == G.vertinfo[i].name) {
39 isIn = true;
40 pos = i;
41 break;
42 }
43 if (!isIn)
44 return; //不在图中,跳出
45
46 visited[pos] = 1; //若在图中,则操作此结点后进行标记
47 //此后pos无用,用来记录邻接点在vertinfo中的位置
48 cout << G.vertinfo[pos].name << '\t';
49 /*
50 function(); //这里仅仅输出
51 */
52 //------------------------------------------------------
53
54 ArcNode *temp; //临时弧指针,指向stapos结点的邻接点
55 temp = G.vertinfo[pos].firstarc;
56 while (temp != NULL)
57 {
58 for (int i = 0; i < G.vexnum; i++) {
59 if (temp->name == G.vertinfo[i].name)
60 {
61 pos = i;
62 break;
63 }
64 }
65 // temp->name 代表的是结点的邻接点名字,要判断visited则要找到在vertinfo中的下标
66
67 //--------------------------------------------
68 if (!visited[pos])
69 dfs_byecursion(G, temp->name);
70 temp = temp->next;
71 }
72 }
73 void travelallnodes_dfs_byecrusion(AdjGraph G) {
74 cout << "dfs all nodes :" << endl;
75 int partnum = 1;
76 for (int i = 0; i < G.vexnum; i++) {
77 if (!visited[i]) {
78 cout << "part " << partnum++ << " :" << endl;
79 dfs_byecursion(G, G.vertinfo[i].name);
80 cout << endl;
81 }
82 }
83 cout << "-----dfs all nodes over!" << endl;
84 }
85 int main()
86 {
87 AdjGraph ag;
88
89 ag.vexnum = 6, ag.arcnum = 5;
90 ArcNode acn[10];
91 ag.vertinfo[0].name = 1;
92 acn[0].name = 2, acn[1].name = 3, acn[2].name = 5;
93 ag.vertinfo[0].firstarc = &acn[0];
94 acn[0].next = &acn[1], acn[1].next = &acn[2], acn[2].next = NULL;
95
96 ag.vertinfo[1].name = 2;
97 acn[3].name = 1, acn[4].name = 4;
98 ag.vertinfo[1].firstarc = &acn[3];
99 acn[3].next = &acn[4], acn[4].next = NULL;
100
101 ag.vertinfo[2].name = 3;
102 acn[5].name = 1, acn[6].name = 5;
103 acn[5].next = &acn[6], acn[6].next = NULL;
104 ag.vertinfo[2].firstarc = &acn[5];
105
106 ag.vertinfo[3].name = 4;
107 acn[7].name = 2, acn[7].next = NULL;
108 ag.vertinfo[3].firstarc = &acn[7];
109
110 ag.vertinfo[4].name = 5;
111 acn[8].name = 3, acn[9].name = 1;
112 acn[8].next = &acn[9], acn[9].next = NULL;
113 ag.vertinfo[4].firstarc = &acn[8];
114
115 ag.vertinfo[5].name = 5;
116 ag.vertinfo[5].firstarc = NULL;
117
118 for (int i = 0; i < ag.vexnum; i++)
119 visited[i] = 0; //初始化递归方法需要使用的visited全局数组
120
121 //第二个参数:结点名字
122 dfs_byecursion(ag, 2);
123 travelallnodes_dfs_byecrusion(ag);
124
125 return 0;
126 }
栈 方法遍历图:
1 void dfs_bystack(AdjGraph G, ElemType stapos) 2 { 3 bool isIn = false; //判断stapos结点是否在图中 4 int pos = 0; //记录结点在vertinfo中的索引 5 for (int i = 0; i < G.vexnum; i++) 6 if (stapos == G.vertinfo[i].name) { 7 isIn = true; 8 pos = i; 9 break; 10 } 11 if (!isIn) 12 return; //不在图中,跳出 13 14 int visited[MAX]; 15 for (int i = 0; i < G.vexnum; i++) visited[i] = 0; 16 17 stack<int> index; //记录顶点索引的栈 18 19 for(int i=0; i// 找到开始点,并标记,打印,入栈 20 if (G.vertinfo[i].name == stapos) { 21 cout << stapos << "\t"; 22 visited[i] = 1; 23 index.push(i); 24 break; 25 } 26 27 while (!index.empty()) 28 { 29 ArcNode *ptemp = G.vertinfo[index.top()].firstarc; //栈顶顶点弧指针 30 int isPushed = 0; //是否有邻接点入栈 31 while (ptemp != NULL) //找栈顶顶点未访问的邻接点 32 { 33 for (int i = 0; i < G.vexnum; i++) 34 { 35 if (ptemp->name == G.vertinfo[i].name && visited[i]) { 36 ptemp = ptemp->next; 37 break; 38 } 39 if (ptemp->name == G.vertinfo[i].name && !visited[i]) { 40 cout << G.vertinfo[i].name << '\t'; 41 index.push(i); 42 visited[i] = 1; 43 isPushed = 1; 44 break; 45 } 46 } 47 if (isPushed) //找到邻接点,出循环 48 break; 49 } 50 51 if (!isPushed) //无邻接点或邻接点全部被访问,栈顶索引出栈 52 { 53 index.pop(); 54 } 55 } 56 }