图的遍历

本文介绍了图的两种基本遍历方法:深度优先搜索(DFS)和广度优先搜索(BFS)。深度优先搜索通过递归方式向下探索尽可能深的路径,而广度优先搜索则按层次顺序访问所有顶点。此外,还提供了这两种方法的Java实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图的遍历是指从图中的任一顶点出发,对图中的所有顶点访问一次且访问一次。图的搜索分为深度优先搜索和广度优先搜索。

1.图的深度优先搜索算法如下:

(1)从图中选取一顶点v,标记顶点v并访问该顶点。

(2)选取顶点v的一个邻结顶点w进行访问,从w开始深度优先搜索。

(3)若从w出发能够访问所有的顶点,则返回到顶点v.

(4)若仍有邻结于v且没有被访问的的顶点,则从该顶点出发搜索其它的路径。否则由顶点v出发的一次搜索过程结束。

从图的深度优先搜索算法中,可以看出图的深度优先搜索是一个递归的过程,简而言之,就是从图的一个顶点出发向下搜索,直到搜索的顶点没有邻结顶点时,然后返回上一层,判断一下有没有顶点没被访问,如果有,就沿之这个顶点向下搜索。否则的话,再返回上一层重复上述的过程。直到所有的顶点都被搜索完为止。所以图的深度优先搜索算法可以用递归来实现。

 

2.图的广度优先搜索算法如下:

访问某个顶点v,接着依次访问它们的邻结顶点w1,w2,....,再访问w1,w2,....的没被访问的邻结顶点。直到所有的顶点都被访问完为止。

图的广度优先搜索算法可用队列来实现,首先让访问顶点v,再让顶点v的所有邻结结点入队列,依次访问它们。然后再让这些邻结结点出队列,访问这些邻结结点的邻结结点。直到队列为空,那么所有结点都被访问了。

 

 

3.图的深度优先搜索与广度优先搜索的JAVA实现

 

package Graph;

/**
 *
 * 建立无向图 用一个数组来存储图节点
 *
 * @author Administrator
 *
 */

public class graph {
 int max;// 图中最大节点数
 int n = 0;// 图中当前节点数
 VexNode[] adjlist;
 boolean visit[];/* 记录节点有没有被访问过 */

 /**
  * 利用邻结矩阵生成邻结表
  *
  * @param vex
  *            顶点数组
  * @param arc
  *            边的一维排列
  * @param n
  *            顶点个数
  */
 public graph(int vex[], int arc[][], int n) {
  this.n = max = n;
  visit = new boolean[n];
  adjlist = new VexNode[n];
  for (int k = 0; k < n; k++) {
   adjlist[k] = new VexNode();
   adjlist[k].Vexdata = vex[k];

  }
  for (int i = 0; i < n; i++) {

   for (int j = 0; j < n; j++) {

    if (arc[i][j] == 1) {

     ArcNode p = new ArcNode();
     p.next = adjlist[vex[i]].firstarc;
     adjlist[vex[i]].firstarc = p;
     p.Arcdata = vex[j];

    }

   }

  }

 }

 public graph(int num) {
  max = num;
  adjlist = new VexNode[num];
  visit = new boolean[num];

 }

 /**
  * 建立图节点
  */

 public void createNode(int data) {
  if (n < max) {
   VexNode v = new VexNode();
   v.Vexdata = data;
   adjlist[n] = v;
   n++;
  }
 }

 /**
  * 建立有向图的边,建立一条从data1到data2的弧
  *
  * @param data1
  * @param data2
  */
 public void createDirectionArc(int data1, int data2) {
  ArcNode p = new ArcNode();
  p.next = adjlist[data1].firstarc;
  adjlist[data1].firstarc = p;
  p.Arcdata = data2;
  adjlist[data2].indegree++;

 }

 /**
  * 建立无向图中的边 即建立邻节表
  */

 public void createArc(int data1, int data2) {
  ArcNode p1;
  ArcNode p2;
  p1 = new ArcNode();
  p2 = new ArcNode();
  p1.next = adjlist[data1].firstarc;
  p2.next = adjlist[data2].firstarc;
  adjlist[data1].firstarc = p1;
  adjlist[data2].firstarc = p2;
  p1.Arcdata = data2;
  p2.Arcdata = data1;

 }

 /**
  * 建立一个有向图逆邻结表
  *
  * @param data1
  * @param data2
  */
 public void createInverseArc(int data1, int data2) {
  ArcNode p = new ArcNode();
  p.next = adjlist[data2].firstarc;
  adjlist[data2].firstarc = p;
  p.Arcdata = data1;

 }

 /**
  * 逆邻结表计算有向图中顶点的入度
  *
  * @param v0
  */
 public void InVex(int v0) {
  ArcNode p = adjlist[v0].firstarc;
  int indegree = 0;
  while (p != null) {
   indegree++;
   p = p.next;
  }

  System.out.println("顶点" + v0 + "的入度为:" + indegree);

 }

 /**
  *
  * 逆邻结表计算顶点的出度
  *
  * @param v0
  */

 public void outVex(int v0) {
  int m = 0;
  for (int i = 0; i < n; i++) {
   ArcNode p = adjlist[i].firstarc;

   if (v0 != i) {
    while (p != null) {
     if (p.Arcdata == v0) {

      m++;
      break;

     } else {
      p = p.next;
     }

    }

   }

  }

  System.out.println("节点" + v0 + "的出度为:" + m);

 }

 /**
  *
  * 邻结表计算有向图中顶点的入度
  *
  */

 public void IndVex(int v0) {
  int m = 0;
  for (int i = 0; i < n; i++) {
   ArcNode p = adjlist[i].firstarc;

   if (v0 != i) {
    while (p != null) {
     if (p.Arcdata == v0) {

      m++;
      break;

     } else {
      p = p.next;
     }

    }

   }

  }

  System.out.println("节点" + v0 + "的入度为:" + m);

 }

 /**
  * 邻结表计算顶点的出度
  *
  */
 public void odvex(int v0) {
  ArcNode p = adjlist[v0].firstarc;
  int m = 0;
  while (p != null) {
   m++;

   p = p.next;

  }

  System.out.println("顶点" + v0 + "的出度为:" + m);

 }

 /**
  *
  * 无向图中求顶点的度
  */

 public void degree(int v0) {
  int m = 0;
  ArcNode p = adjlist[v0].firstarc;
  while (p != null)

  {

   m++;
   p = p.next;
  }

  System.out.println("顶点" + v0 + "的度为:" + m);

 }

 /**
  * 图的深度遍历 即从第一个节点出发,直接节点的next为空时,返回上一层进行遍历 因此它是一个递归算法 从v0出发开始遍历
  */

 public void visitdepth(int v0) {
  ArcNode v = adjlist[v0].firstarc;
  System.out.print(adjlist[v0].Vexdata + " ");
  visit[v0] = true;
  while (v != null) {
   if (!visit[v.Arcdata]) {

    visitdepth(v.Arcdata);
   }

   v = v.next;

  }

 }

 public void dfs(int v0) {

  for (int i = 0; i < visit.length; i++)
   visit[i] = false;
  for (int j = 0; j < 4; j++)
   if (!visit[j])
    visitdepth(j);

 }

 /**
  *
  * 图的广度遍历,又称为层次遍历 把预先遍历的结点放入到队列中,然后出队节点进行遍历,直到队列为空
  *
  * @param v0
  */
 public void bfs1(int v0) {

  int[] queue = new int[max + 10];
  ArcNode p;
  int front = 1;
  int rear = 1;
  int v;
  System.out.print(v0 + " ");
  visit[v0] = true;
  queue[rear] = v0;
  rear = rear + 1;
  while (front != rear) {
   v = queue[front];
   front = front + 1;
   p = adjlist[v].firstarc;

   while (p != null) {
    if (!visit[p.Arcdata]) {

     System.out.print(p.Arcdata + " ");
     queue[rear] = p.Arcdata;
     visit[p.Arcdata] = true;
     rear = rear + 1;

    }

    p = p.next;

   }

  }

 }

 public void bfs(int v0) {
  for (int i = 0; i < visit.length; i++)
   visit[i] = false;
  for (int j = 0; j < max; j++)
   if (!visit[j])
    bfs1(j);

 }
}

 

 

以上就是图的深度优先遍历与广度优先遍历的实现算法。深度优先搜索算法是用递归来实现的,广度优先搜索是用队列来实现的。

关于深度优先搜索与广度优先搜索的实例请参考http://sjjg.js.zwu.edu.cn/SFXX/tu/tu5.3.2.html

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值