数据结构——邻接表实现图的深度优先遍历与广度优先遍历

#include<iostream>
using namespace std;
#define MAX_VERTEX_NUM 6
struct ArcNode
{
    int adjvex; //该弧所指向的顶点
    ArcNode *nextarc; //指向下一条弧的指针
    int info;  //该弧的相关信息
};
typedef struct VNode
{
    int data;   //顶点信息
    ArcNode *firstarc;  //指向第一条依附该顶点的弧的指针
    int kind;   //点的标记
}VNode,AdjList[MAX_VERTEX_NUM];
struct ALGraph
{
    AdjList vertices;
    int vexnum ,arcnum;  //当前顶点数和弧数
    void assignment(int i,int j ,int w);
    void print();
    int locate(int data);
};
typedef struct QNode
{
    int data;
    QNode *next;
}*QueuePtr;
struct LinkQueue   //队列
{
    QueuePtr frontd;
    QueuePtr rear;
    void Insert(int datad);
    int  Del();
    int  QueueEmpty();
    void print();
};
/**********队列插入***********/
void LinkQueue::Insert(int datad)
{
    if(frontd==NULL)
    {
        frontd=new QNode;
        frontd->data=datad;
        frontd->next=NULL;
        rear=frontd;
    }
    else
    {
        QNode *m;
        m->data=datad;
        m->next=NULL;
        rear->next=m;
        rear=rear->next;
    }
}
/**************队头出列***********/
int LinkQueue::Del()
{
    int m=frontd->data;
    if(frontd->next==NULL)
    {
        frontd=NULL;
        return m;
    }
    frontd=frontd->next;
    return m;
}
/**************队列判断是否为空*********/
int LinkQueue::QueueEmpty()
{
    if(frontd==NULL)
        return 0;
    else return 1;
}
/**************打印队列*****************/
void  LinkQueue::print()
{
    QNode *k=frontd;
    while(k!=NULL)
    {
       cout<<k->data;
       k=k->next;
    }
}
/**************初始化**********************/
void initgraph(ALGraph &graph)
{
    int  i ;
    graph.vexnum=0;
    graph.arcnum=0;
    for(i=0;i<MAX_VERTEX_NUM;i++)
    {
        graph.vertices[i].data=0;
        graph.vertices[i].firstarc=NULL;
        graph.vertices[i].kind=0;
    }
}
/*************赋值***********************/
void ALGraph::assignment(int i,int j,int w)
{
    int k;
    arcnum++; //弧数+1
    for(k=0;k<vexnum;k++)  //判断该起点是否已经被记录,若已经记录了则用k记录下位置
    {
        if(vertices[k].data==i)
            break;
    }
    if(k==vexnum)   //若未被记录则增加一个点数(未加入超出情况)
    {
        vertices[vexnum].data=i;
        ArcNode *m=new ArcNode;
        m->adjvex=j; //指针必须要有->符号
        m->info=w;
        m->nextarc=NULL;
        vertices[vexnum].firstarc=m;
        vexnum++;
    }
    else     //若已经被记录,则只增加边的信息
    {
        ArcNode *m=new ArcNode;
        m->adjvex=j; //指针必须要有->符号
        m->info=w;
        m->nextarc=NULL;
        ArcNode *p=vertices[k].firstarc; //定位到边的表尾
        while(p->nextarc!=NULL)
        {
            p=p->nextarc;
        }
        p->nextarc=m;
    }
}

/***************打印******************/
void ALGraph::print()
{
    int k;
    for (k=0;k<vexnum;k++)
    {
        ArcNode *m=vertices[k].firstarc;
        while(m!=NULL)
        {
            cout<<vertices[k].data<<' ';
            cout<<m->adjvex<<' ';
            cout<<m->info<<endl;
            m=m->nextarc;
        }
    }
}
/**************集合赋值******************/
void as(ALGraph &graph)
{
    graph.assignment(0,1,3);//赋值
    graph.assignment(0,2,3);
    graph.assignment(0,3,3);
    graph.assignment(0,4,3);
    graph.assignment(0,5,3);
    graph.assignment(1,5,2);
    graph.assignment(1,0,3);
    graph.assignment(1,2,2);
    graph.assignment(2,1,2);
    graph.assignment(2,3,4);
    graph.assignment(2,0,3);
    graph.assignment(2,4,3);
    graph.assignment(3,4,4);
    graph.assignment(3,0,3);
    graph.assignment(3,2,4);
    graph.assignment(4,3,4);
    graph.assignment(4,0,3);
    graph.assignment(4,5,1);
    graph.assignment(4,2,2);
    graph.assignment(5,4,1);
    graph.assignment(5,1,2);
    graph.assignment(5,0,3);
}
/**************定位点在表中的位置**********/
int ALGraph::locate(int idata)
{
    int v;
    for (v=0;v<vexnum;v++) //寻找
        {
            if(vertices[v].data==idata)
                break;
        } //若找不到便是一开始的时候赋值为错的
    return v;
}
/***************深度优先************/
void DFS(ALGraph &graph,int v)   //从第v个顶点开始访问(仅仅支持连通图,若有多个连通分支,则需要再设置一个引用dfs的函数
{
    ArcNode *m=graph.vertices[v].firstarc;
    cout<<graph.vertices[v].data<<' ';
    graph.vertices[v].kind=1;
    while(m!=NULL)
    {
        v=graph.locate(m->adjvex);//寻找m->adjvex的位置
        if(graph.vertices[v].kind==0)
            DFS(graph,v);
        m=m->nextarc;
    }
}
/**************广度优先搜索***********/
void BFS(ALGraph &graph,int v) //从第v个开始,依然只适用与连通图cout<<1;
{
    int i=0;
    int u;
    LinkQueue qu;
    qu.frontd=qu.rear=NULL;//初始化
    qu.Insert(graph.vertices[v].data);
    while(qu.QueueEmpty())
    {

        u=qu.Del();
        cout<<u<<' ';
        v=graph.locate(u);
        graph.vertices[v].kind=1;
        ArcNode *m=graph.vertices[v].firstarc;
        while(m!=NULL)
        {
            v=graph.locate(m->adjvex);
            cout<<graph.vertices[v].data<<' ';
            if(graph.vertices[v].kind!=0)
            {
                qu.Insert(graph.vertices[v].data);
            }
            m=m->nextarc;
        }
    }

}
int main()
{
    int v=1;
    ALGraph graph;
    initgraph(graph); //初始化(忘初始化数据异常)
    cout<<"建立有向图"<<endl;
    as(graph);//赋值
    graph.print();//打印
    cout<<"深度优先搜索的顺序:"<<endl;
    DFS(graph,v-1);//数组是从0开始
    initgraph(graph);
    as(graph);
    cout<<endl;
    cout<<"广度优先搜索的顺序:"<<endl;
    BFS(graph,v-1);//数组是从0开始
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值