1 public class Graph {
2 //标记节点是否已访问过了
3 private boolean[] isVisit = {false,false,false,false,false,false,false,false,false,false};
4
5 public static void main(String[] args) {
6 new Graph().table();
7 }
8
9 /**
10 *
11 * @Title: matrix
12 * @Description: TODO 图的邻接矩阵表示
13 * @param 设定文件
14 * @return void 返回类型
15 * @throws
16 */
17 public void matrix() {
18
19 //顶点表
20 Node[] nodes = {new Node(0),new Node(1),new Node(2),new Node(3),new Node(4)};
21
22
23
24 //无向图的临接矩阵存储,对称矩阵,这个矩阵描述了图的边集合
25 //边表, 不带权,i表示行标, j表示列标.第i行表示第i个定点(i对应nodes顶点的key值和下标),
26 //第i个节点指向的节点key 作为j的下标, 赋值1,表示有连接
27 int[][] table = {
28 {0, 1, 0, 1, 0},//第0号定点指向了第1号节点和第3号节点
29 {1, 0, 0, 1, 0},
30 {0, 0, 0, 0, 0},
31 {1, 1, 0, 0, 1},
32 {0, 0, 0, 1, 0},
33 };
34
35 //有向图,
36 //第i行的非0节点,表示顶点i的出度
37 //第i列的非0节点,表示顶点i的入度
38 //定点不能指向自己,主对角线为0
39 int[][] table2 = {
40 {0, 1, 0, 1, 0},//第0号节点指向了第1号节点和第3号节点
41 {1, 0, 0, 0, 1},
42 {0, 0, 0, 0, 0},
43 {1, 0, 1, 0, 1},
44 {0, 1, 0, 1, 0},
45 };
46
47 //对于带权边的表示:用权值替换1,用MAX_VALUE替换0
48 }
49
50 /**
51 *
52 * @Title: table
53 * @Description: TODO 图的临接表表示
54 * @param 设定文件
55 * @return void 返回类型
56 * @throws
57 */
58 public void table() {
59
60 //临接表表示法类似与 HashMap 的存储结构.数组与链表组合.数组的每个节点都是一个链表的头结点
61 //顶点表
62 Vertex_node[] nodes = {new Vertex_node(0),new Vertex_node(1),new Vertex_node(2),new Vertex_node(3),new Vertex_node(4)};
63
64 //有向图
65 nodes[0].head = new Side_node(1,new Side_node(4,null));//指向1号和4号节点
66 nodes[1].head = new Side_node(2,new Side_node(3,null));//指向3号和2号节点
67 nodes[2].head = new Side_node(1,null); //指向1号节点
68 nodes[3].head = new Side_node(0,new Side_node(4,null));//指向0/4号节点
69 nodes[4].head = new Side_node(1,null); //指向1号节点
70
71 //数组元素表示顶点,数组元素的链表,表示这个元素的边集合
72
73 //每个顶点的初度是边表的长度
74 //入度需要扫描整个临接表,
75
76 //对于带权边的表示:需要在 side_node 类中添加一个 value 域,存放权值
77
78
79 printGraph(nodes);
80
81 //图的遍历
82 //深度优先搜素
83
84
85 //深度优先搜索
86 System.out.println("深度优先搜索");
87 DFS(nodes,0);
88
89 for(int i = 0; i < isVisit.length; i++) {
90 isVisit[i] = false;
91 }
92
93 //广度优先搜索
94 System.out.println("广度优先搜索");
95 BFS(nodes,0);
96
97
98
99
100
101 }
102
103 /**
104 * @Title: BFS
105 * @Description: TODO 广度优先搜索
106 * @param @param nodes 邻接表方式存储的 顶点集合
107 * @param @param index 第一个访问的顶点,index应小于nodes.length
108 * @return void 返回类型
109 * @throws
110 */
111 private void BFS(Vertex_node[] nodes, int index) {
112 //队列用LinkedList
113 Queue<Integer> queue = new LinkedList<Integer>();
114
115
116
117 //访问第一个节点
118 if(index >= 0 && index < nodes.length) {
119
120 isVisit[index] = true;
121 System.out.println("visited :"+nodes[index].key);
122 queue.add(nodes[index].key);//入队
123 }
124
125 //循环条件是队列不为null
126 while(!queue.isEmpty()) {
127 int idx = queue.poll();//出队
128
129 Side_node n = nodes[idx].head;
130 while(n != null) {
131
132 // if the node is not visited, visit that and add that to queue
133 if(!isVisit[n.key]) {
134 //visite
135 isVisit[n.key] = true;
136 System.out.println("visited :"+n.key);
137 //入队列
138 queue.add(n.key);
139 }
140
141 n = n.next;
142
143 }
144
145
146 }
147
148 }
149
150
151
152 /**
153 *
154 * @Title: DFS
155 * @Description: TODO 深度优先搜索
156 * @param @param nodes 邻接表方式存储的 顶点集合
157 * @param @param index 第一个访问的顶点,index应小于nodes.length
158 * @return void 返回类型
159 * @throws
160 */
161 private void DFS(Vertex_node[] nodes, int index) {
162 //节点 index 是否已访问
163 if(isVisit[index] || index >= nodes.length) {
164 return;
165 }
166 //访问, --print
167 isVisit[index] = true;
168 System.out.println("visited :"+nodes[index].key);
169
170 //递归nodes[index]出度节点
171 Side_node n = nodes[index].head;
172 while(n != null) {
173 if(!isVisit[n.key])
174 DFS(nodes, n.key);
175 n = n.next;
176
177 }
178
179 }
180
181 private void printGraph(Vertex_node[] nodes) {
182 // TODO Auto-generated method stub
183 for(Vertex_node n : nodes) {
184 System.out.print(n.key+":--> ");
185
186 Side_node n1 = n.head;
187 while(n1 != null) {
188 System.out.print(n1.key+" --> ");
189 n1 = n1.next;
190
191 }
192
193 System.out.println();
194 }
195
196 }
197
198 class Node{
199 public int key;//节点的名称.比如第key号节点,不可重复
200 public int value;//权值
201
202 public Node(int key) {
203 super();
204 this.key = key;
205 }
206 public Node(int key, int value) {
207 super();
208 this.key = key;
209 this.value = value;
210 }
211 public Node() {
212 }
213
214
215 }
216
217
218 /**
219 *
220 * @ClassName: Vertex_node
221 * @Description: TODO 临接表表示方式的 顶点类
222 * @author: zw
223 * @date: 2018年3月26日 下午3:17:46
224 */
225 class Vertex_node{
226 public int key;//节点的名称.比如第key号节点,不可重复
227
228 public Side_node head;//出度链表的首结点
229
230 public Vertex_node(int key) {
231 super();
232 this.key = key;
233 }
234 public Vertex_node(int key, Side_node head) {
235 super();
236 this.key = key;
237 this.head = head;
238 }
239 public Vertex_node() {
240 }
241
242
243 }
244
245 /**
246 *
247 * @ClassName: Side_node
248 * @Description: TODO 临接表表示方式的 边表节点类
249 * @author: zw
250 * @date: 2018年3月26日 下午3:18:39
251 */
252 class Side_node{
253 public int key;//节点的名称.比如第key号节点,不可重复
254
255 public Side_node next;//兄弟节点
256
257 public Side_node(int key) {
258 super();
259 this.key = key;
260 this.next = null;
261 }
262 public Side_node(int key, Side_node next) {
263 super();
264 this.key = key;
265 this.next = next;
266 }
267 public Side_node() {
268 }
269
270 }
271 }
0:--> 1 --> 4 -->
1:--> 2 --> 3 -->
2:--> 1 -->
3:--> 0 --> 4 -->
4:--> 1 -->
深度优先搜索
visited :0
visited :1
visited :2
visited :3
visited :4
广度优先搜索
visited :0
visited :1
visited :4
visited :2
visited :3