算法和数据结构(11)图2 --应用篇

题目1:拯救007

在这里插入图片描述
如图所示,007在一个初始位置的岛上,岛的四周为湖泊,假设湖泊内有若干的鳄鱼,鳄鱼静止不动,湖泊的周围是岸边,007采取的拯救方案为:从岛跳至鳄鱼的头上,在跳至另一只鳄鱼的头上,假设007每次跳动的长度为1,写程序,求007能否跳到岸边;
在这里插入图片描述
可以把每只鳄鱼看作一个点;在这里插入图片描述
如图所示,把每个鳄鱼的点,看作为一个结点,就可以把这个问题看作为图的dfs或者bfs来进行求解,只有两点之间的距离小于007可跳的范围,即两结点之间存在边;

那么思考选择bfs还是dfs,哪种算法更好呢?
很明显,深度优先更好,因为我们的最终退出条件为跳到岸边即可;

代码如下:

public class LiveOrDie {
    private Node[] crocodiles;//鳄鱼的结点
    private int xEdge;//x轴上的边界,若设为50,即范围-50~50
    private int yEdge;//y轴上的边界,若设为50,即范围-50~50
    private Node startPos;//007开始位置

    class Node {
        int x;
        int y;
        boolean visited;

        public Node(int x, int y) {
            this.x = x;
            this.y = y;
            this.visited = false;
        }
		//用来判断边是否存在
        public boolean canJump(Node node) {
            int x1 = this.x - node.x;
            int y1 = this.y - node.y;
            double distance = Math.sqrt(Math.pow(x1, 2) + Math.pow(y1, 2));
            return distance < 1;
        }
    }

    public boolean liveOrDie(Node node) {
        if ((Math.abs(node.x) - xEdge) < 1 || (Math.abs(node.y) - yEdge) < 1) return true;
        node.visited = true;
        for (int i = 0; i < crocodiles.length; i++) {
            if (node.canJump(crocodiles[i]) && !crocodiles[i].visited) {
                return liveOrDie(crocodiles[i]);
            }
        }
        return false;
    }
}

注意:此题目中,并没有实现图的数据结构,因为也没有必须去实现,此题目中涉及的图,其数据结构仅仅多了一层有无边的关系,此题中,我们可以在Node类中,通过visted和canJump方法进行直接判断边是否存在;
若实现的图数据结构,无论是邻接表还是邻接矩阵,这个答案的求得都会更加的麻烦;

题目2:六度空间
一个数学领域的猜想,名为Six Degrees of Separation, 理论指出:你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过6个中间人你就能够认识任何一个陌生人;

在这里插入图片描述

即你通过你认识的人的关系层,当这个关系层大于6时,你可以认识任何一个人;

给定社交网络图,请对每个结点计算符合“六度空间”理论结点占总结点的百分比

转换为代码的语言:在给定的一个图的数据结构中,从一个结点出发,相外拓展6次和它有边的结点,是否包含六这个图的所有结点?

考虑算法,向外拓展6层;很明显这道题要运用广度优先,BFS;并且只能做6层,并且需要保存访问到了的结点;
bfs复习:

public void bfs(Vertex v){
	Queue que = new Queue();
	v.visited = true;
	que.add(v);
	while(!que.isEmpty){
    Vertex v2 = que.pop();
		for(v2的邻接点:w){	
			que.add(w);
			w.visited = true;
		}
	}
}

此题目伪代码:

int bfs(Vertex x){
	int level = 0;//层数;
	int count = 1;//此人肯定认识自己;
	Vertx last = x;
	Queue queue = new Queue();//得到队列对象
	queue.add(x);
	x.visited = true;
	while(!queue.isEmpty()){
		Vertex v = queue.pop();
		vertex  tail;
		for(v的邻接结点 w:v){
			if(!w.visited){
				w.visited = true;
				queue.add(w);
				count++;
				tail=w;
			}
		}
		//逻辑,每一层的bfs时,当for循环结束时,tail指向了其这一层的最后结点,保存起来;
		//v=last时,表示这一层意见循环结束了,level应该+1了;
		if(v == last){
			level++;
			last = tail;//last等于其这一层的最后一个结点
		}
		if(level == 6) break;
	}
	return count;
}
发布了17 篇原创文章 · 获赞 0 · 访问量 359

猜你喜欢

转载自blog.csdn.net/qq_32193775/article/details/104146261
今日推荐