图和两种遍历,Saving James Bond

图可以作为表示指定环境内所有对象的关系的形式。树可以认为是图的子集,图中节点的联系可能是成环的。

图的元素包括边和点,按照不同的需要可能侧重表达点之间的关系或者点本身的信息。

int graph[100][100] = {0};
...

void InsertEdge(int ver_a, int ver_b, int weight)
{
    graph[ver_a][ver_b] = weight;
    return;
}

如上例所示为侧重表示边的图,可以使用二维数组存储这样的图,而数组的序号作为点的代号。上例中的 graph[1][2] 即表示“从 1 点 到 2 点的值(这个值可能是距离或者其他指定含义的值)”,而 graph[2][1] 就是“从 2 到 1 的值”了。

如果给出了一系列对象之间的联系,就可以简单地为这些对象编个号,然后在矩阵中定义它们之间的边。


还有一种表示形式是记录点而非边,这在一个给定的坐标系内比较常见。

int vertex[100][2] = {0};
bool isVertex[100] = {0};
...

void InsertVertex(int x, int y, int num)
{
    vertex[num][0] = x;
    vertex[num][1] = y;
    isVertex[num] = true;
    return;
}


和上一种形式相比它较不直观,如果要为这些点定义边可能需要其他手段 (比如根据两点间距离判断,如果它们足够近就认为是联通的)。

bool IsEdge(int x1, int x2, int y1, int y2, int lenth)
{
    return (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) <= lenth*lenth;
}


遍历整个图的方式包括 深度优先搜索 (Depth First Search, DFS) 和 广度优先搜索 (Breadth First Search, BFS)。

深度优先搜索,行为类似二叉树的前序遍历。即从起点开始,每访问一个节点便查询该节点的邻接点并访问找到的第一个邻接点,直到访问的节点没有未访问过的邻接点,再从最近访问过的点中寻找还可以访问的点。

void BFS(int vertexNum)
{
    Visited[vertexNum] = true;    //访问当前节点
    for (int w = 0; w < GraphLen; w++)
    {
        if (!Visited[w] && IsEdge(vertexNum, w))    //对所有未访问过、且是当前点的邻接点的 w
            DFS(w);
    }
    return;
}


广度优先搜索,行为类似二叉树的层序遍历。和层序遍历一样,广度优先搜索需要一个队列来保存访问某个点时该点的所有邻接点。

void BFS(int vertexNum)
{
    visited[vertexNum] = true;
    EnQueue(queue, vertexNum);
    
    while (!EmptyQueue(queue))
    {
        v = PopQueue(queue);        //从队列中弹出的点用于查找所有的邻接点进队列
        for (w = 0; w < GraphLen; w++)
        {
            if (!Visited[w] && IsEdge(v, w));
                {
                    Visited[w] = True;
                    EnQueue(w);
                }
        }
    }
    return;
}

下面是两道关于图遍历的题目,见于 中国大学MOOC-陈越、何钦铭-数据结构 在PTA发布的习题。题目背景如下:


/*
This time let us consider the situation in the movie "Live and Let Die" in which James Bond, the world's most famous spy, was captured by a group of drug dealers.
现在让我们假设《Live and Die》中詹姆斯邦德的处境,世界顶级的间谍被一组毒贩俘虏。
He was sent to a small piece of land at the center of a lake filled with crocodiles.
他被扔到一个湖心的小孤岛上,湖中遍是鳄鱼。
There he performed the most daring action to escape -- he jumped onto the head of the nearest crocodile!
他要通过一
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值