图的基本操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CJL2313/article/details/79043941

实验四

实验名称:图的基本操作

实验室名称:丹青909

实验台号:14

学生姓名: 陈佳龙

专业班级: 2015级1班

指导教师:于慧伶

实验日期:2017-6-11

一、实验目的

1、掌握图的存储思想及其存储实现。

2、掌握图的深度、广度优先遍历算法思想及其程序实现。

3、掌握图的常见应用算法的思想及其程序实现。

二、实验仪器及环境:

    PC计算机;windows XP操作系统Visual C++6.0、CodeBlocks

三、实验内容及结果(按照具体实验题目,按照如下格式书写)

 1、

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <string.h>

#include <stack>

#define INFMAX 9999999

#define MAXVEX 200

using namespace std;

typedef char VertexType;

typedef int EdgeType;

int visited[INFMAX];

typedef struct EdgeNode /* 边表结点  */

{

    int adjvex;    /* 邻接点域,存储该顶点对应的下标 */

    EdgeType info;      /* 用于存储权值,对于非网图可以不需要 */

    struct EdgeNode *next; /* 链域,指向下一个邻接点 */

}EdgeNode;

typedef struct VertexNode /* 顶点表结点 */

{

    VertexType data; /* 顶点域,存储顶点信息 */

    EdgeNode *firstedge;/* 边表头指针 */

}VertexNode, AdjList[MAXVEX];

typedef struct

{

    AdjList adjList;

    int numNodes,numEdges; /* 图中当前顶点数和边数 */

}GraphAdjList;

void  CreateALGraph(GraphAdjList *G)

{

    int i,j,k,weight;

    EdgeNode *e;

    cout<<"输入顶点数和边数:";

    cin>>G->numNodes>>G->numEdges;   /* 输入顶点数和边数 */

    for(i = 0;i < G->numNodes;i++)   /* 读入顶点信息,建立顶点表 */

    {

        cout<<"请输入顶点信息:";

        cin>>G->adjList[i].data;    /* 输入顶点信息 */

        G->adjList[i].firstedge=NULL;    /* 将边表置为空表 */

    }

    for(k = 0;k < G->numEdges;k++)/* 建立边表 */

    {

        cout<<"输入边(vi,vj)上的顶点序号:";

        cin>>i>>j; /* 输入边(vi,vj)上的顶点序号 */

        e=(EdgeNode *)malloc(sizeof(EdgeNode)); /* 向内存申请空间,生成边表结点 */

        e->adjvex=j;                 /* 邻接序号为j */

        e->next=G->adjList[i].firstedge;  /* 将e的指针指向当前顶点上指向的结点 */

        G->adjList[i].firstedge=e;       /* 将当前顶点的指针指向e */

        //e=(EdgeNode *)malloc(sizeof(EdgeNode)); /* 向内存申请空间,生成边表结点 */

       // e->adjvex=i;                 /* 邻接序号为i */

       // e->next=G->adjList[j].firstedge;  /* 将e的指针指向当前顶点上指向的结点 */

       // G->adjList[j].firstedge=e;       /* 将当前顶点的指针指向e */

    }

}

void DispGraphAdjList(GraphAdjList *G)

{

    int i;

    EdgeNode *p;

    cout<<"有向图的邻接表表示如下:"<<endl;

    printf("%6s%6s%12s\n","编号","顶点","相邻边编号");

    for(i=0;i< G->numNodes;i++)

    {

        printf("%4d %6c",i,G->adjList[i].data);//

        for(p=G->adjList[i].firstedge;p!=NULL;p=p->next)

            printf("%4d",p->adjvex);

        cout<<endl;

    }

}

void  DepthFirstSearch(GraphAdjList G,int v){

    EdgeNode *p;

    cout<<v<<endl;

    visited[v]=1;

    p=G.adjList[v].firstedge;

    while(p!=NULL){

        if(!visited[p->adjvex])

            DepthFirstSearch(G,p->adjvex);

        p=p->next;

    }

}

void DFSTraveGraph(GraphAdjList G){

    int v;

    for(v=0;v<G.numNodes;v++){

        visited[v]=0;

    }

    for(v=0;v<G.numNodes;v++){

            if(!visited[v])

            DepthFirstSearch(G,v);

    }

}

void calculator(GraphAdjList G)//有向图各节点的度

{

 EdgeNode *p;

 int num1,num2;

 cout<<"有向图邻接表的各节点度输出显示为:"<<endl;

 for(int i=0;i<G.numNodes;i++)

 {

  num1=0;

  cout<<G.adjList[i].data<<" ";

  p=G.adjList[i].firstedge;

  while(p)//计算出度

  {

   num1++;

   p=p->next;

  }

  cout<<"出度为:"<<num1<<" ";

  num2=0;

  for(int j=0;j<G.numNodes;j++)//计算入度

  {

   if(i!=j)

   {

    p=G.adjList[j].firstedge;

    while(p)

    {

     if(p->adjvex==i)

     {

      num2++;

      break;

     }

     p=p->next;

    }

   }

  }

  cout<<"入度为:"<<num2<<" ";

  cout<<"度为:"<<num2+num1<<endl;

 }

}

int *getInDegree(GraphAdjList *g) {

    int *inDegreeArray = (int *) malloc(g->numNodes * sizeof(int));

    memset(inDegreeArray, 0, g->numNodes * sizeof(int));

    int i;

    EdgeNode *pCrawl;

    for(i = 0; i < g->numNodes; i++) {

        pCrawl = g->adjList[i].firstedge;

        while(pCrawl) {

            inDegreeArray[pCrawl->adjvex]++;

            pCrawl = pCrawl->next;

        }

    }

    return inDegreeArray;

}

void topologicalSort(GraphAdjList *g) {

    int *inDegreeArray = getInDegree(g);

    //Stack * = initStack();

    stack<int> zeroInDegree;

    int i;

    for(i = 0; i < g->numNodes; i++) {

        if(inDegreeArray[i] == 0)

            zeroInDegree.push(i);

    }

    EdgeNode *pCrawl;

    while(!zeroInDegree.empty()) {

        i = zeroInDegree.top();

        zeroInDegree.pop();

        //printf("vertex %d\n", i);

        cout<<i<<endl;

        pCrawl = g->adjList[i].firstedge;

        while(pCrawl) {

            inDegreeArray[pCrawl->adjvex]--;

            if(inDegreeArray[pCrawl->adjvex] == 0)

                zeroInDegree.push(pCrawl->adjvex);

            pCrawl = pCrawl->next;

        }

    }

}

int main(void)

{

    GraphAdjList G;

    CreateALGraph(&G);

    DispGraphAdjList(&G);

    calculator(G);

    cout<<"有向图的深度优先递归遍历为:"<<endl;

    DFSTraveGraph(G);

    cout<<"有向图的拓扑排序序列为:"<<endl;

    topologicalSort(&G);

    return 0;

}

7、

四、实验心得体会:(包括遇到的问题及解决办法)

图的存储结构分为邻接表和邻接矩阵,拓扑排序时用了栈,将入度为0的节点先输出。有向图与无向图的区别。

五、指导教师意见及成绩

                                  签名:

                                                 

猜你喜欢

转载自blog.csdn.net/CJL2313/article/details/79043941