数据结构实验之图的邻接表存储及图的遍历(广度优先和深度优先)

前言

建立图的邻接表存储结构,并以以0结点为起点实现上述图的深度优先和广度优先遍历算法;
数据结构实验之图的邻接表存储及图的遍历(广度优先和深度优先)_第1张图片

邻接表的建立:

邻接表存储图的实现方式是,给图中的各个顶点独自建立一个链表,用节点存储该顶点,用链表中其他节点存储各自的邻接点。

#include<iostream>
using namespace std;
#define  MAX_VERTEX_NUM 20//最大顶点个数
#define  VertexType int//顶点数据的类型
#define  InfoType int//图中弧或者边包含的信息的类型

typedef struct ArcNode {
     
    int adjvex;//邻接点在数组中的位置下标
    struct ArcNode* nextarc;//指向下一个邻接点的指针
    InfoType info;//边的信息
}ArcNode;
typedef struct VNode {
     
    VertexType data;//顶点的数据域
    ArcNode* firstarc;//指向邻接点的指针
}VNode, AdjList[MAX_VERTEX_NUM];//存储各链表头结点的数组
typedef struct {
     
    AdjList vertices;//图中顶点的数组
    int vexnum, arcnum;//记录图中顶点数和边或弧数
}ALGraph;

//判断该点在数组中的位置
int LocateVex(ALGraph G, int V)
{
     
    for (int i = 0; i < G.vexnum; ++i)
    {
     
        if (G.vertices[i].data == V)
        {
     
            return i;
        }
    }
    return -1;
}

void CreateUDG(ALGraph& G)
{
     
    //采用邻接表创建无向图
    cin >> G.vexnum >> G.arcnum;//输入总顶点数和总边数
    for (int i = 0; i < G.vexnum; ++i)
    {
     
        cin >> G.vertices[i].data;//输入顶点值
        G.vertices[i].firstarc = NULL;//初始化指针域为null

    }
    int i, j;
    ArcNode* p1,*p2;
    for (int k = 0; k < G.arcnum; ++k)
    {
     
        int v1, v2,info;//相邻的两个顶点,边的权重
        cin >> v1 >> v2>>info;//输入一条边的两个顶点
        i = LocateVex(G, v1);
        j = LocateVex(G, v2);//确定v1,v2在G中的位置
        p1 = (ArcNode*)malloc(sizeof(ArcNode));//生成一个新的边界点p1
        p1->adjvex = j;//邻接点在数组中的位置为j
        p1->info = info;
        p1->nextarc = G.vertices[i].firstarc;
        G.vertices[i].firstarc = p1;
        //将新节点*p1插入到顶点vi的边表头部
        p2 = new ArcNode;//生成一个新的边界点p2
        p2->adjvex = i;//邻接点序列号为i
        p2->info = info;
        p2->nextarc = G.vertices[j].firstarc;
        G.vertices[j].firstarc = p2;
        //将新节点*p2插入到顶点vj的边表头部
    }
}

//输出
void display(ALGraph G)
{
     
    ArcNode *temp = NULL;
    for (int i = 0; i < G.vexnum; i++)
    {
     
        cout << "顶点:" << G.vertices[i].data << "的邻接点有:";
        temp = G.vertices[i].firstarc;
        while (temp)
        {
     
            cout << temp->adjvex << " ";
            temp = temp->nextarc;
        }
        cout << endl;
       
    }
}

int main()
{
     
    ALGraph A;
    CreateUDG(A);
    display(A);
    

深度优先算法实现

所谓深度优先搜索,是从图中的一个顶点出发,每次遍历当前访问顶点的临界点,一直到访问的顶点没有未被访问过的临界点为止。然后采用依次回退的方式,查看来的路上每一个顶点是否有其它未被访问的临界点。访问完成后,判断图中的顶点是否已经全部遍历完成,如果没有,以未访问的顶点为起始点,重复上述过程。(深度优先搜索是一个不断回溯的过程。

//深度优先遍历,v为第一个开始遍历的节点
     //设置全局数组,记录标记顶点是否被访问过
 bool visited[20] = {
      false };
 int w;
void DFSDisplay( const ALGraph G,int v)
{
        
   cout << v<<" ";
   visited[v] = true;
   ArcNode *p = G.vertices[v].firstarc;
   while (p != NULL)
   {
     
       w = p->adjvex;
       if (! visited[w])
       {
     
           DFSDisplay(G, w);
       }
       p = p->nextarc;
   }
}

广度优先算法实现

广度优先算法类似树的层次遍历,从图中的某一顶点出发,遍历每一个顶点时,依次遍历其所有的邻接点,然后再从这些邻接点出发,同样依次访问它们的邻接点。按照此过程,直到图中所有被访问过的顶点的邻接点都被访问到。最后还需要做的操作就是查看图中是否存在尚未被访问的顶点,若有,则以该顶点为起始点,重复上述遍历的过程。

//广度优先遍历
void BFSDisplay(ALGraph G,int v)
{
     
  //将用做标记的visit数组初始化为false
  for (int i = 0; i < G.vexnum; ++i) {
     
      visited[i] = false;
  }
  queue<int> q;//建立队列
  q.push(v);
  visited[v] = true;//已访问设置值为true
  while (!q.empty())
  {
     
      v = q.front();//获取队首
      ArcNode* p = G.vertices[v].firstarc;
      while (p)
      {
     
          if (visited[p->adjvex] == false)
          {
     
              q.push(p->adjvex);
              visited[p->adjvex] = true;
          }
          p = p->nextarc;
      }
      cout << q.front() << " ";
      q.pop();
  }
}

你可能感兴趣的:(数据结构,数据结构)