关于图的一些算法

来源:互联网 发布:head设计模式不会java 编辑:程序博客网 时间:2024/05/29 06:45

图可以用邻接表和邻接矩阵表示

一.邻接矩阵:

    1.邻接矩阵的生成(无向图):

    数据结构:

<pre name="code" class="cpp">typedef struct  {      char v[maxNum];//图的顶点信息      int e[maxNum][maxNum];//图的顶点信息      int vNum;//顶点个数      int eNum;//边的个数  }graph;  

   2.邻接矩阵的生成

void createGraph(graph *g)//创建图g    {        cout<<"正在创建无向图..."<<endl;        cout<<"请输入顶点个数vNum:";        cin>>g->vNum;        cout<<"请输入边的个数eNum:";        cin>>g->eNum;        int i,j;            //初始画图g        for(i=1;i<=g->vNum;i++)            for(j=1;j<=g->vNum;j++)                g->e[i][j]=0;            //输入边的情况        cout<<"请输入边的头和尾"<<endl;        for(int k=1;k<=g->eNum;k++)        {            cin>>i>>j;            g->e[i][j]=1;            g->e[j][i]=1;        }    }  
3.邻接矩阵的深度优先(递归):

void dfs(graph *g,int i)  {      //cout<<"顶点"<<g->v[i]<<"已经被访问"<<endl;      cout<<"顶点"<<i<<"已经被访问"<<endl;      visited[i]=1;//标记顶点i被访问      for(int j=0;j<g->vNum;j++)      {          if(g->e[i][j]!=0&&visited[j]==0)              dfs(g,j);      }  }    void DFS(graph *g)  {      int i;      //初始化visited数组,表示一开始所有顶点都未被访问过      for(i=0;i<g->vNum;i++)          visited[i]=0;      //深度优先搜索      for(i=0;i<g->vNum;i++)          if(visited[i]==0)//如果这个顶点为被访问过,则从i顶点出发进行深度优先遍历              dfs(g,i);  }

3.1 深度优先遍历的非递归算法伪代码





</pre>4.邻接矩阵的广度优先(要用到队列):<p></p><p></p><pre name="code" class="cpp">void BFS(graph *g);//广度优先遍历图g        void bfs(graph *g,int i)  {      int k,j;      cout<<"顶点"<<i<<"已经被访问"<<endl;        visited[i]=1;//标记顶点i被访问             q.push(i);      while(!q.empty())      {          k=q.front();          q.pop();          //cout<<q.size();          for(j=1;j<=g->vNum;j++)          {              if(g->e[k][j]!=0&&visited[j]==0)              {                  cout<<"顶点"<<j<<"已经被访问"<<endl;                  visited[j]=1;                  q.push(j);              }          }      }  }  


二.邻接表

1.邻接表的数据结构:“

typedef struct node     //边表结点{    int adjvex;         //邻接点域    struct node *next;  //域链    //若是要表示边上的权,则应增加一个数据域}EdgeNode;typedef struct vnode    //顶点边结点{    VertexType vertex;  //顶点域    EdgeNode *firstedge;//边表头指针}VertexNode;typedef VertexNode AdjList[MaxVertexNum];   //AdjList是邻接表类型typedef struct{    AdjList adjlist;    //邻接表    int n, e;           //图中当前顶点数和边数}ALGraph;

2.邻接表的生成

void CreateGraphAL(ALGraph *G){    int i, j, k;    EdgeNode * s;    printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");    scanf("%d,%d", &(G->n), &(G->e));       // 读入顶点数和边数       printf("请输入顶点信息(输入格式为:顶点号<CR>)每个顶点以回车作为结束:\n");    for (i = 0; i < G->n; i++)              // 立有n个顶点的顶点表       {        scanf("\n%c", &(G->adjlist[i].vertex)); // 读入顶点信息           G->adjlist[i].firstedge = NULL;            // 点的边表头指针设为空       }    printf("请输入边的信息(输入格式为:i,j):\n");    for (k = 0; k < G->e; k++)      // 建立边表       {        scanf("\n%d,%d", &i, &j); // 读入边<Vi,Vj>的顶点对应序号           s = new EdgeNode;         // 生成新边表结点s           s->adjvex = j;         // 邻接点序号为j           s->next = G->adjlist[i].firstedge; // 将新边表结点s插入到顶点Vi的边表头部           G->adjlist[i].firstedge = s;        s = new EdgeNode;        s->adjvex = i;        s->next = G->adjlist[j].firstedge;        G->adjlist[j].firstedge = s;    }}

3.邻接表的深度优先

void DFS(ALGraph *G, int i){    //以vi为出发点对邻接表表示的图G进行深度优先搜索    EdgeNode *p;    printf("visit vertex:%c\n", G->adjlist[i].vertex);  // 访问顶点vi    visited[i] = TRUE;              //标记vi已访问    p = G->adjlist[i].firstedge;        //取vi边表的头指针    while (p)    {                               //依次搜索vi的邻接点vj,这里j=p->adjvex        if (!visited[p->adjvex])    //若vi尚未被访问            DFS(G, p->adjvex);      //则以Vj为出发点向纵深搜索        p = p->next;                     //找vi的下一邻接点    }}void DFSTraverseM(ALGraph *G){    int i;    for (i = 0; i < G->n; i++)        visited[i] = FALSE;    for (i = 0; i < G->n; i++)        if (!visited[i])            DFS(G, i);}

4.邻接表的广度优先

typedef struct{    int front;    int rear;    int count;    int data[QueueSize];}CirQueue;void InitQueue(CirQueue *Q){    Q->front = Q->rear = 0;    Q->count = 0;}int QueueEmpty(CirQueue *Q){    return Q->count == 0;}int QueueFull(CirQueue *Q){    return Q->count == QueueSize;}void EnQueue(CirQueue *Q, int x){    if (QueueFull(Q))        printf("Queue overflow");    else    {        Q->count++;        Q->data[Q->rear] = x;        Q->rear = (Q->rear + 1) % QueueSize;    }}int DeQueue(CirQueue *Q){    int temp;    if (QueueEmpty(Q))    {        printf("Queue underflow");        return NULL;    }    else    {        temp = Q->data[Q->front];        Q->count--;        Q->front = (Q->front + 1) % QueueSize;        return temp;    }}void BFS(ALGraph*G, int k){   // 以vk为源点对用邻接表表示的图G进行广度优先搜索    int i;    CirQueue Q;             //须将队列定义中DataType改为int    EdgeNode *p;    InitQueue(&Q);          //队列初始化    printf("visit vertex:%c\n", G->adjlist[k].vertex);      //访问源点vk    visited[k] = TRUE;    EnQueue(&Q, k);         //vk已访问,将其人队。(实际上是将其序号人队)    while (!QueueEmpty(&Q))    {                                   //队非空则执行        i = DeQueue(&Q);                    //相当于vi出队        p = G->adjlist[i].firstedge;        //取vi的边表头指针        while (p)        {                               //依次搜索vi的邻接点vj(令p->adjvex=j)            if (!visited[p->adjvex])            {                           //若vj未访问过                printf("visit vertex:%c\n", G->adjlist[p->adjvex].vertex);      //访问vj                visited[p->adjvex] = TRUE;                EnQueue(&Q, p->adjvex); //访问过的vj人队            }            p = p->next;                    //找vi的下一邻接点        }    }}void BFSTraverseM(ALGraph *G){    int i;    for (i = 0; i < G->n; i++)        visited[i] = FALSE;    for (i = 0; i < G->n; i++)        if (!visited[i])            BFS(G, i);}





0 0
原创粉丝点击