数据结构学习笔记(七)--图
2016-04-13 22:29
465 查看
图的存储方式一般分为邻接矩阵与邻接链表。矩阵操作简单,但稀疏图时采用链表效率更高。
图的遍历:DFS(用递归实现) BFS(用队列实现,类似于树的层序遍历!)
注意什么时候使用DFS什么时候使用BFS更好?
**如果估计目标顶点离开起始顶点不会太远,那么选择广度优先遍历是比较合适的,因为广度优先是一种由近及远的搜索策略;
如果估计目标顶点与起始顶点没有太大的关系,那么选择深度优先遍历是比较合适的,深度优先是通过邻接点尽快接近较远目标的搜索策略。
所以,大多数题目还是用广度优先为佳,毕竟深度优先是个递归的程序,而广度优先可以写成循环。
适合用深度的,大概就是上面所说的,已经对目标定点的位置有了模糊的印象,并经判断合适。**
解决实际问题时,有必要每次都把图的结构表示成矩阵或链表吗?其实不必。图只是一个抽象概念,方便我抽象实际问题,有时候世界用一个二维数组表示邻接矩阵就可以完全解决问题了。
如练习中的列出连通子集:
Saving James Bond - Easy Version
图的遍历:DFS(用递归实现) BFS(用队列实现,类似于树的层序遍历!)
注意什么时候使用DFS什么时候使用BFS更好?
**如果估计目标顶点离开起始顶点不会太远,那么选择广度优先遍历是比较合适的,因为广度优先是一种由近及远的搜索策略;
如果估计目标顶点与起始顶点没有太大的关系,那么选择深度优先遍历是比较合适的,深度优先是通过邻接点尽快接近较远目标的搜索策略。
所以,大多数题目还是用广度优先为佳,毕竟深度优先是个递归的程序,而广度优先可以写成循环。
适合用深度的,大概就是上面所说的,已经对目标定点的位置有了模糊的印象,并经判断合适。**
解决实际问题时,有必要每次都把图的结构表示成矩阵或链表吗?其实不必。图只是一个抽象概念,方便我抽象实际问题,有时候世界用一个二维数组表示邻接矩阵就可以完全解决问题了。
如练习中的列出连通子集:
#include <cstdio> #define N 15 void ListComponentsWithDFS(); void ListComponentsWithBFS(); void DFS(int V); void BFS(int V); void InitVisit(void); int n; bool Visited ; int G = {0}; int main() { int E; scanf("%d%d", &n, &E); for (int i = 0; i < E; i++) { int a, b; scanf("%d%d", &a, &b); G[b][a] = G[a][b] = 1; } ListComponentsWithDFS(); InitVisit(); ListComponentsWithBFS(); return 0; } void ListComponentsWithDFS() { for (int V = 0; V < n; V++) if (!Visited[V]) { printf("{ "); DFS(V); printf("}\n"); } } void ListComponentsWithBFS() { for (int V = 0; V < n; V++) if (!Visited[V]) { printf("{ "); BFS(V); printf("}\n"); } } void DFS(int V) { Visited[V] = true; printf("%d ", V); for (int i = 0; i < n; i++) { if (G[V][i] && !Visited[i]) DFS(i); } } void BFS(int V) { const int MAX_SIZE = 100; int Queue[MAX_SIZE]; int first = -1, last = -1; Queue[++last] = V; //入队 Visited[V] = true; while (first < last) //当队不为空时 { int F = Queue[++first]; //出队 printf("%d ", F); for (int i = 0; i < n; i++) { if (G[F][i] && !Visited[i]) { Queue[++last] = i; //入队 Visited[i] = true; } } } } void InitVisit() { for (int i = 0; i < N; i++) Visited[i] = false; }
习题:拯救007
利用遍历连通子集的思想。Saving James Bond - Easy Version
/*拯救007*/ /*by zoe*/ #include <cmath> #include <cmath> #include <cstdio> #include <fstream> #include <iostream> #define YES 1 #define NO 0 using namespace std; struct Point { int num; int x; int y; Point &operator=(Point P) { num = P.num; x = P.x; y = P.y; return *this; } }; Point M[102][102]; Point P[102]; bool visited[102]; int nu; // int ne; int D; bool Jump(Point P, Point V) { if (sqrt((P.x - V.x) * (P.x - V.x) + (P.y - V.y) * (P.y - V.y)) < D) return true; else return false; } bool FirstCanJump(Point P) { // printf("judge first can jump:%f\n", sqrt(P.x * P.x + P.y * P.y)); if (sqrt(P.x * P.x + P.y * P.y) < D) return true; else return false; } bool IsSafe(Point P) { if (fabs(P.x - 50) < D || fabs(P.y - 50) < D) return true; else return false; } int DFS(Point Pv) { // printf("DFS start!\n"); int answer; Point V; visited[Pv.num] = true; if (IsSafe(Pv)) answer = YES; else { // printf("not the end\n"); for (int i = 0; i < nu; i++) { V = P[i]; if (!visited[V.num] && Jump(Pv, V)) { answer = DFS(V); if (answer == YES) break; } } } return answer; } void Save007(Point Pv) { int answer; for (int i = 0; i < nu; i++) { Pv = P[i]; if (!visited[Pv.num] && FirstCanJump(Pv)) { // printf("first can jump\n"); answer = DFS(Pv); if (answer == YES) break; } // Pv = P[i]; } if (answer == YES) printf("Yes\n"); else printf("No\n"); } int main() { int i; // string S; cin >> nu >> D; // cout << nu << " " << D << endl; if (nu <= 0) printf("No\n"); for (i = 0; i < nu; i++) P[i].num = i; for (i = 0; i < nu; i++) { scanf("%d%d\n", &P[i].x, &P[i].y); // cout << i << endl; // cout << i << " " << P[i].x << " " << P[i].y << endl; } for (i = 0; i < nu; i++) visited[i] = 0; // cout << 0 << " " << P[0].x << " " << P[0].y << endl; Save007(P[0]); /*int i, a[6]; for (i = 0; i < 5; i++) cin >> a[i]; cout << a[4] << endl;*/ return 0; }
相关文章推荐
- 数据结构与算法习题汇总(3)
- 数据结构实验之求二叉树后序遍历和层次遍历
- 数据结构实验之二叉树四:还原二叉树
- Huffman树的简单实现
- 数据结构中八大排序算法
- 用于并行计算的多线程数据结构,第 2 部分: 设计不使用互斥锁的并发数据结构
- 用于并行计算的多线程数据结构,第 1 部分: 设计并发数据结构
- 栈的数组表示
- 从键盘读入n个整数(升序),请编写算法实现: 建立带表头结点的单链表; 显示单链表,(形如:H->10->20->30->40); 在有序单链表中插入新的数据元素x; 将单链表就地逆
- C语言实现的数据结构之------哈希表
- LRU Cache数据结构
- Java数据结构——哈希表
- YTUOJ之逆序输出单词(串)
- HDU 4411最小费用流
- 考研中的算法时间复杂度求解
- java中的数据结构
- 数据结构图的运算(深度优先)
- 数据结构与算法-第12章二叉树和其他树-001遍历集合的所有子集
- linux内核数据结构之kfifo(实现)
- 数据结构(java)——栈及其应用