数据结构之实验三:图的遍历操作与拓扑排序算法

一、实验目的:

1.掌握图的存储定义;

2.掌握图的遍历操作;

3.掌握图的拓扑排序算法。

二、实验内容:

1. 利用图的邻接矩阵,实现图的深度优先遍历搜索。图结构如下
结果输出
在这里插入图片描述

2. 采用邻接表作为有向图的存储结构,编写图的拓扑排序程序实现下图的拓扑排序输出;
在这里插入图片描述

实验一:图的深度优先遍历操作

定义邻接矩阵

typedef struct{
    int vex[MaxVertexNum];
    int Edge[MaxVertexNum][MaxVertexNum];
    int vexnum,arcnum;  //顶点数和边数
}MGraph;

寻找v的位置

int LocateVex(int vex,MGraph G)
{
    for(int i=0;i<G.vexnum;i++)
    {
        if(vex==G.vex[i])
            return i;
    }
    return -1;
}

创建无向图

void CreateGraph(MGraph &G)
{
    int i,j;
    cout <<"请输入总顶点数和总边数:";
    cin >> G.vexnum >> G.arcnum;
    //初始化数组Edge;
    for(i=0;i<G.vexnum;i++)
    {
        for(j=0;j<G.vexnum;j++)
            G.Edge[i][j]=0;
    }
    cout<<"请输入点的名称  "<<endl;
    for(i=0;i<G.vexnum;i++)
    {
        cout<<"请输入第" << (i+1) << "个点的名称:";
        cin>>G.vex[i];
    }
    for(i=0;i<G.arcnum;i++)
    {
        int v1,v2,n,m;
        cout<<"请输入第"<<(i+1)<<"个边的依附点的名称: ";
        cin>>v1>>v2;
        n=LocateVex(v1, G);
        m=LocateVex(v2, G);
        G.Edge[n][m]=1;
        G.Edge[m][n]=1;
    }
}

无向图的深度优先遍历

bool visit[MaxVertexNum];
void DFS(MGraph G,int v)
{
    int k;
    cout<<G.vex[v]<<"    ";
    visit[v]=true;
    for(k=0;k<G.vexnum;k++)
    {
        if((!visit[k]) && G.Edge[v][k]!=0)
        {
            DFS(G,k);
        }
    }   
}

主函数

int main() {
    MGraph G;
    CreateGraph(G);
    cout<<"无向图创建完成"<<endl;
    int v;
    cout<<"请输入无向遍历的起始点:";
    cin>>v;
    //初始化辅助数组visit
    for(int i=0;i<G.vexnum;i++)
    {
        visit[i]=false;
    }
    DFS(G,v);
    return 0;
}
结果输出

在这里插入图片描述

实验二:拓扑排序算法
#define MaxVertexNum 100

//定义边表
typedef struct ArcNode{
    int adjvex;     //下一个结点的关键字
    struct ArcNode *nextarc; //指向下一个结点的指针
}ArcNode;
//创建图结点
typedef struct VNode{
    int data;
    ArcNode *firstedge; //边表的头指针
}VNood;
//定义邻接表
typedef struct{
    VNode adjmulist[MaxVertexNum];
    VNode converse_adjmulist[MaxVertexNum];
    int vexnum,arcnum;
}AMLGraph;

//定义顺序栈
typedef struct{
    int *top,*base;
    int stacksize;
} spStack;

//定义入度矩阵
int Indegree[MaxVertexNum];

//定义栈
spStack S;

栈的系列操作

//初始化顺序栈
void InitStack(spStack &S)
{
    S.base = new int[MaxVertexNum];
    if(!S.base) exit(1);
    S.top = S.base;
    S.stacksize = MaxVertexNum;
}

// 进栈
void Push(spStack &S,int i)
{
    // 满栈
    if(S.top-S.base == S.stacksize)
        return;
    *S.top++ = i;
}
//出栈
void Pop(spStack &S,int &i)
{
    //栈空
    if(S.top == S.base)
        return;
    i = *--S.top;
}

//判断栈是否为空栈
bool IsEmptyStack(spStack S)
{
    if(S.base == S.top)
        return true;
    return false;
}
//找到位置
int LocateVex(AMLGraph G,int v)
{
    for(int i = 0;i < G.vexnum; i++)
    {
        if(v == G.adjmulist[i].data)
            return i;
    }
    return -1;
}
//寻找入度
void FindIndegree(AMLGraph G)
{
    int i,count;
    for(i = 0 ; i < G.vexnum ; i++)
    {
        count = 0;
        ArcNode *p = G.converse_adjmulist[i].firstedge;
        while(p){
            p = p->nextarc;
            count++;
        }
        Indegree[i] = count;
    }
}

创建有向图的邻接表

void CreateUDG(AMLGraph &G)
{
    int i;
    cout<<"请输入总顶点数和总边数:  ";
    cin>>G.vexnum>>G.arcnum;
    for(i = 0; i < G.vexnum; i++)
    {
        cout<<"请输入第"<<(i+1)<<"个点的名称:  ";
        cin>>G.adjmulist[i].data;
        G.converse_adjmulist[i].data = G.adjmulist[i].data;
        G.adjmulist[i].firstedge=NULL;
        G.converse_adjmulist[i].firstedge=NULL;
    }
    for(i = 0; i < G.arcnum; i++)
    {
        int v1,v2,m,n;
        cout<<"请输入第"<<(i+1)<<"个点的依附点:  ";
        cin>>v1>>v2;
        m = LocateVex(G, v1);
        n = LocateVex(G, v2);
        
        ArcNode *p1 = new ArcNode; //生成新结点p1
        p1->adjvex = n;
        p1->nextarc = G.adjmulist[m].firstedge;
        G.adjmulist[m].firstedge = p1; //将新结点插入边表头部,头插法
        
        ArcNode *p2 = new ArcNode; //生成新结点p2
        p2->adjvex = m;
        p2->nextarc = G.converse_adjmulist[n].firstedge;
        G.converse_adjmulist[n].firstedge = p2; //将新结点插入逆序边表的头部
    }
}

拓扑排序

bool TopologicalSort(AMLGraph G,int topo[])
{
    int i,count;
    InitStack(S);
    FindIndegree(G);
    for(i = 0 ; i < G.vexnum ; i++)
    {
        if(Indegree[i] == 0)
            Push(S, i);
    }
    count = 0;
    while(!IsEmptyStack(S))
    {
        Pop(S, i);
        topo[count] = i;
        ++count;
        ArcNode *p = new ArcNode;
        for(p = G.adjmulist[i].firstedge ; p ; p = p->nextarc)
        {
            int k = p->adjvex;
            --Indegree[k];
            if(Indegree[k] == 0) Push(S,k);
        }
    }
    //输出结点个数与图的结点个数做比较
    if(count < G.vexnum) return false;
    else return true;
}

主函数

int main() {
    AMLGraph G;
    CreateUDG(G);
    cout<<"有向图的邻接表、逆序邻接表创建完成"<<endl<<endl;
    int *topo = new int[MaxVertexNum];
    if(TopologicalSort(G, topo))
    {
        cout<<"该有向图的拓扑排序为:"<<endl;
        for(int i = 0 ; i<G.vexnum; i++)
        {
            cout<<G.adjmulist[topo[i]].data<<",  ";
        }
        cout<<endl;
    }
    else cout<<"图中存在环,无法输出拓扑排序";
    return 0;
}
结果输出在这里插入图片描述
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值