数据结构学习之图的遍历(邻接表和邻接矩阵)

数据结构学习之图的遍历(邻接表和邻接矩阵)

0x1 问题描述

​ 建立一个邻接表和邻接矩阵的算法

0x2 代码如下

#include <iostream>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#define MAXV 1000+7
#define INF 32767

using namespace std;
//邻接矩阵结构
typedef struct
{
    int no;
    //InfoType info;
}VertextType;
typedef struct
{
    int edge[MAXV][MAXV];
    int n; //vertex number
    int e; //edge number
    VertextType vers[MAXV];
}MatGraph;

// 创建图
void CreateMat(MatGraph *&g,int n, int e)
{
    //Init
    int i=0,j=0,v=0;
    g->n=n;
    g->e=e;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            if(i!=j)
                g->edge[i][j]=INF;
            else
                g->edge[i][j]=0;
    for(int n=1;n<=e;n++)
    {
        cin>>i>>j>>v;
        g->edge[i][j]=v;
    }
}

// 输出图
void DispMat(MatGraph *g)
{
    for(int i=0;i<g->n;i++)
        for(int j=0;j<g->n;j++)
        {
            cout<< g->edge[i][j] <<"\t";
            if(j==g->n-1)
                cout<<endl;
        }
}

// 销毁图
void DestroyMat(MatGraph *&g)
{
    free(g);
}

//邻接表结构
typedef struct ANode
{
    int adjvex;
    struct ANode *nextarc; //指向下一条边的指针
    int weight;
}ArcNode;

typedef struct Vnode
{
    //InfoType info;
    ArcNode *firstarc; //指向第一个边结点
}VNode;

typedef struct
{
    int n;
    int e;
    VNode adjlist[MAXV]; //邻接表的头结点数组
}AdjGraph;


//创建邻接表
void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e)
{
    ArcNode *p;
    G=(AdjGraph *)malloc(sizeof(AdjGraph));
    for(int i=0;i<n;i++)
        G->adjlist[i].firstarc=NULL;
    for(int i=0;i<n;i++)
        for(int j=n-1;j>=0;j--)
        {
            if(A[i][j]!=0 && A[i][j]!=INF)
            {
                //insert head method
                p=(ArcNode *)malloc(sizeof(ArcNode));
                p->adjvex=j;
                p->weight=A[i][j];
                p->nextarc=G->adjlist[i].firstarc;
                G->adjlist[i].firstarc=p;
            }
        }
    G->n=n;
    G->e=e;
}

//输出邻接表
void DispAdj(AdjGraph *G)
{
    ArcNode *p;
    for(int i=0;i<G->n;i++)
    {
        p=G->adjlist[i].firstarc;
        printf("%3d:",i);
        while(p!=NULL)
        {
            printf("%3d[%d]",p->adjvex,p->weight);
            p=p->nextarc;
        }
        printf("\n");
    }
}

// 销毁邻接表
void DestroyAdj(AdjGraph *&G)
{
    ArcNode *pre,*p;
    for(int i=0;i<G->n;i++)
    {
        p=G->adjlist[i].firstarc;
        while(p!=NULL)
        {
            pre=p;
            p=p->nextarc;
            free(pre);
        }
    }
    free(G);
}

int main()
{
    int n,e;
    cout<< "Please input the number of vertex(n) and edge(e):"<<endl;
    cin>>n>>e;
    MatGraph *G = (MatGraph *)malloc(sizeof(MatGraph));
    CreateMat(G,n,e);
    DispMat(G);
    AdjGraph *g;
    CreateAdj(g,G->edge,n,e);
    DispAdj(g);
    DestroyAdj(g);
    DestroyMat(G)
    return 0;
}

0x3 问题描述

> 实现图的遍历算法
>
> ![image-20190514151953196](https://ws2.sinaimg.cn/large/006tNc79ly1g30vea93y4j31880kaws5.jpg)

数据如下:

6 9
0 1 5
1 2 4
3 2 5
4 3 5
5 4 1
2 0 8
2 5 9
0 3 7
3 5 6

0x4 代码如下

附加说明:

​ 这里我对两种存储结构,邻接表和邻接矩阵,每种都分别写了DFS的递归和非递归遍历、BFS遍历。

​ 网上很多代码其实有错误的,我检验了下自己的代码,觉得还ok.

#include <iostream>
#include <string.h>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
#define MAXV 1000+7
#define INF 32767

using namespace std;
//邻接矩阵结构
typedef struct
{
    int no;
    //InfoType info;
}VertextType;
typedef struct
{
    int edge[MAXV][MAXV];
    int n; //vertex number
    int e; //edge number
    VertextType vers[MAXV];
}MatGraph;

// 创建图
void CreateMat(MatGraph *&g,int n, int e)
{
    //Init
    int i=0,j=0,v=0;
    g->n=n;
    g->e=e;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            if(i!=j)
                g->edge[i][j]=INF;
            else
                g->edge[i][j]=0;
    for(int n=1;n<=e;n++)
    {
        cin>>i>>j>>v;
        g->edge[i][j]=v;
    }
}

// 输出图
void DispMat(MatGraph *g)
{
    for(int i=0;i<g->n;i++)
        for(int j=0;j<g->n;j++)
        {
            cout<< g->edge[i][j] <<"\t";
            if(j==g->n-1)
                cout<<endl;
        }
}

// 销毁图
void DestroyMat(MatGraph *&g)
{
    free(g);
}

//邻接表结构
typedef struct ANode
{
    int adjvex;
    struct ANode *nextarc; //指向下一条边的指针
    int weight;
}ArcNode;

typedef struct Vnode
{
    //InfoType info;
    int d;
    ArcNode *firstarc; //指向第一个边结点
}VNode;

typedef struct
{
    int n;
    int e;
    VNode adjlist[MAXV]; //邻接表的头结点数组
}AdjGraph;

typedef struct
{
    int n;
    ArcNode *d;
}Node;


//创建邻接表
void CreateAdj(AdjGraph *&G,int A[MAXV][MAXV],int n,int e)
{
    ArcNode *p;
    G=(AdjGraph *)malloc(sizeof(AdjGraph));
    for(int i=0;i<n;i++)
        G->adjlist[i].firstarc=NULL;
    for(int i=0;i<n;i++)
        for(int j=n-1;j>=0;j--)
        {
            if(A[i][j]!=0 && A[i][j]!=INF)
            {
                //insert head method
                p=(ArcNode *)malloc(sizeof(ArcNode));
                p->adjvex=j;
                p->weight=A[i][j];
                p->nextarc=G->adjlist[i].firstarc;
                G->adjlist[i].firstarc=p;
            }
        }
    G->n=n;
    G->e=e;
}

//输出邻接表
void DispAdj(AdjGraph *G)
{
    ArcNode *p;
    for(int i=0;i<G->n;i++)
    {
        p=G->adjlist[i].firstarc;
        printf("%3d:",i);
        while(p!=NULL)
        {
            printf("%3d[%d]",p->adjvex,p->weight);
            p=p->nextarc;
        }
        printf("\n");
    }
}

// 销毁邻接表
void DestroyAdj(AdjGraph *&G)
{
    ArcNode *pre,*p;
    for(int i=0;i<G->n;i++)
    {
        p=G->adjlist[i].firstarc;
        while(p!=NULL)
        {
            pre=p;
            p=p->nextarc;
            free(pre);
        }
    }
    free(G);
}


/*
data
6 9
0 1 5
1 2 4
3 2 5
4 3 5
5 4 1
2 0 8
2 5 9
0 3 7
3 5 6
*/

//recrusive method DFS
int visted[MAXV];
void DFS(AdjGraph *G,int v)
{
    ArcNode *p;
    visted[v]=1;
    printf("%2d",v);
    p = G->adjlist[v].firstarc;
    while(p!=NULL)
    {
        if(visted[p->adjvex]==0)
            DFS(G,p->adjvex);
        else
            p=p->nextarc;
    }
}

// 邻接矩阵dfs
void dfs(MatGraph *G,int v)
{
    visted[v]=1;
    printf("%2d",v);
    for(int i=0;i<G->n;i++)
    {
        if(G->edge[v][i]<INF && visted[i]==0 && G->edge[v][i]!=0)
            dfs(G,i);
    }
}
// not recrusive method DFS
//  失败
void DfsStack(AdjGraph *G,int v)
{
    //ArcNode *p;
    Node v1,v2;
    stack<Node>s;
    memset(visted,0,sizeof(visted));
    v1.n=v;
    v1.d=G->adjlist[v].firstarc;
    visted[v1.n]=1;
    printf("%2d",v1.n);
    s.push(v1);
    while(!s.empty())
    {
        v1=s.top();
        bool find=false;
        while(v1.d!=NULL && !find)
        {
            if(visted[v1.d->nextarc->adjvex]==0)
                find=true;
            else
            {
                v1.d = v1.d->nextarc;
            }
        }
        if(find)
        {
            v2.n=G->adjlist[v1.d->nextarc->adjvex].firstarc->adjvex;
            v2.d=G->adjlist[v1.d->nextarc->adjvex].firstarc;
            printf("%2d",v1.n);
            s.push(v2);
            visted[v2.n]=1;
        }else
        {
            s.pop();
            //visted[v1.n]=0;
        }
    }
    printf("\n");
}

void DFS_STACK(AdjGraph *G,int v)
{
    stack<int>s;
    ArcNode *p;
    int booked[MAXV];
    for(int i=0;i<G->n;i++)
        booked[i]=0;
    s.push(v);
    printf("%2d",v);
    booked[v]=1;
    p=G->adjlist[v].firstarc;
    while(!s.empty())
    {
        int v1=s.top();
        p=G->adjlist[v1].firstarc;
        while(p)
        {
            if(booked[p->adjvex]==0)
            {
                printf("%2d",p->adjvex);
                booked[p->adjvex]=1;
                s.push(p->adjvex);
                p=G->adjlist[p->adjvex].firstarc;
            }else
            {
                p=p->nextarc;
            }

        }
        if(p==NULL)
            s.pop();

    }
}

void dfs_stack(MatGraph *G,int v)
{
    stack<int> s;
    int i;
    int booked[MAXV];
    for(int i=0;i<G->n;i++)
        booked[i]=0;
    s.push(v);
    booked[v]=1;
    printf("%2d",v);
    while(!s.empty())
    {
        int v1=s.top();
        for(i=0;i<G->n;i++)
        {
            if(G->edge[v1][i]<INF && booked[i]==0 && G->edge[v1][i]!=0)
            {
                printf("%2d",i);
                s.push(i);
                booked[i]=1;
                break;
            }
        }
        if(i==G->n)
            s.pop();
    }
}
/*
void DFSTraverse(AdjGraph *G,int v)
{
    int top=-1;
    int j;
    printf("%2d",v);
    visted[v]=1;
    stack[++top]=v;
    while(top!=-1)
    {
        v=stack[top];
        for(int i=0;i<G.n;i++)
        {
            if(G)
        }
    }
}
*/


// BFS

void BFS(AdjGraph *G,int v)
{
    queue<int>q;
    ArcNode *p;
    int visted[MAXV];
    for(int i=0;i<G->n;i++)
        visted[i]=0;
    printf("%2d",v);
    visted[v]=1;
    q.push(v);
    while(!q.empty())
    {
        int v1=q.front();
        q.pop();
        p=G->adjlist[v1].firstarc;
        while(p!=NULL)
        {
            if(visted[p->adjvex]==0)
            {
                printf("%2d",p->adjvex);
                visted[p->adjvex]=1;
                q.push(p->adjvex);
            }
            p=p->nextarc;
        }
    }
    printf("\n");
}

void bfs(MatGraph *G,int v)
{
    queue<int> q;
    int booked[MAXV];
    for(int i=0;i<G->n;i++)
        booked[i]=0;
    q.push(v);
    booked[v]=1;
    printf("%2d",v);
    while(!q.empty())
    {
        int v1=q.front();
        q.pop();
        for(int i=0;i<G->n;i++)
        {
            if(G->edge[v1][i]<INF && booked[i]==0 && G->edge[v][i]!=0)
            {
                printf("%2d",i);
                q.push(i);
                booked[i]=1;
            }
        }
    }
}


int main()
{
    int n,e;
    cout<< "Please input the number of vertex(n) and edge(e):"<<endl;
    cin>>n>>e;
    MatGraph *G = (MatGraph *)malloc(sizeof(MatGraph));
    CreateMat(G,n,e);
    DispMat(G);
    AdjGraph *g;
    CreateAdj(g,G->edge,n,e);
    DispAdj(g);
    memset(visted,0,sizeof(visted));
    printf("遍历邻接表Start\n");
    DFS(g,0);
    printf("\n");
  	//非递归遍历
    DFS_STACK(g,0);
    printf("\n");
    BFS(g,0);
    printf("\n遍历邻接矩阵Start\n");
    memset(visted,0,sizeof(visted));
    dfs(G,0);
    printf("\n");
  	//非递归遍历
    dfs_stack(G,0);
    printf("\n");
    bfs(G,0);
    return 0;
}

0x5 结果如下

image-20190514152115977

posted @ 2019-05-14 15:25  xq17  阅读(646)  评论(0编辑  收藏  举报