关于图的一些算法

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

一.邻接矩阵:

    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);
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值