zoukankan      html  css  js  c++  java
  • 图的一些简单算法实现

    1、类型声明

    邻接矩阵

    #define MAXV<最大顶点个数>
    #define INF 32767   //定义∞
    typedef struct
    {
        int no;   //顶点编号
        InfoType info;   //顶点其他信息
    }VertexType;   //顶点类型
    typedef struct
    {
        int edges[MAXV][MAXV];   //邻接矩阵数组
        int n,e;   //顶点数,边数
        VertexType vexs[MAXV];   //存放顶点信息
    }MatGraph;   //邻接矩阵类型
    

    邻接表

    typedef struct ANode
    {
        int adjvex;   //该边的邻接点编号
        struct ANode *nextarc;   //指向下一条边的指针
        int weight;   //权值
    }ArcNode;
    typedef struct Vnode
    {
        InfoType info;   //顶点其他信息
        ArcNode *firstarc;   //指向第一个边结点
    }VNode;   //邻接表的头结点类型
    typedef struct
    {
        VNode adjlist[MAXV];   //邻接表的头结点数组
        int n,e;   //顶点数和边数
    }AdjGraph;   //邻接表类型
    

    2、不带权有向图邻接矩阵

    void InDs1(MatGraph g) //求每个顶点的入度
    {
        int i,j,n;
        printf("各顶点入度:
    ");
        for(j=0;j<g.n;j++)
        {
            n=0;
            for(i=0;i<g.n;i++)
            {
                if(g.edges[i][j]!=0)
                {
                    n++; //累计入度数
                }
            }
            printf("顶点%d:%d
    ",j,n);
        }
    }
    
    void OutDs1(MatGraph g) //求每个顶点的出度
    {
        int i,j,n;
        printf("各顶点出度:
    ");
        for(i=0;i<g.n;i++)
        {
            n=0;
            for(j=0;j<g.n;j++)
            {
                if(g.edges[i][j]!=0)
                {
                    n++; //累计出度数
                }
            }
        	printf("顶点%d:%d
    ",i,n);
        }
    }
    
    void ZeroOutDs1(MatGraph g) //求出度为0的顶点
    {
        int i,j,n;
        printf("出度为0的顶点:
    ");
        for(i=0;i<g.n;i++)
        {
            n=0;
            for(j=0;j<g.n;j++)
            {
                if(g.edges[i][j]!=0)
                {
                    n++;
                }
                if(n==0)
                {
                    printf("2d
    ",i);
                }
            }
        }
        printf("
    ");
    }
    

    3、不带权有向图邻接表

    void InDs2(AdjGraph *G) //求每个顶点的入度
    {
        ArcNode *p;
        int A[MAXV],i; //A存放各顶点的入度
        for(i=0;i<G->n;i++) //A中元素初始值0
        {
            A[i]=0;
            
        }
        for(i=0;i<G->n;i++) //扫描所有头结点
        {
            p=G->adjlist[i].firstarc;
            while(p!=NULL) //扫描边结点
            {
                A[p->adjvex]++; //表示i到p->adjvex顶点有一条边
                p=p->nextarc;
            }
        }
        printf("各顶点的入度:
    ");
        for(i=0;i<G->n;i++)
        {
            printf("顶点%d:%d
    ",i,A[i]);
        }
    }
    
    void OutDs2(AdjGraph *G) //求每个顶点的出度
    {
        int i,n;
        ArcNode *p;
        printf("各顶点出度为:
    ");
        for(i=0;i<G->n;i++) //扫描所有头结点
        {
            n=0;
            p=G->adjlist[i].firstarc;
            while(p!=NULL) //扫描边结点
            {
                n++;
                p=p->nextarc;
            }
            printf("顶点%d:%d
    ",i,n);
        }
    }
    
    void ZeroOutDs2(AdjGraph *G) //出度为0的顶点数
    {
        int i,n;
        ArcNode *p;
        printf("出度为0的顶点数:
    ");
        for(i=0;i<G->n;i++) //扫描所有头结点
        {
            n=0;
            p=G->adjlist[i].firtarc;
            while(p!=NULL) //扫描边结点
            {
                n++;
                p=p->nextarc;
            }
            if(n==0) //输出出边为0的顶点编号
            {
                printf("%2d",i);
            }
        }
        printf("
    ");
    }
    

    4、判断是否存在经过顶点v的回路

    int visited[MAXV]; //全局变量数组
    void Cycle(AdjGraph *G,int u,int v,int d,bool &has)
    {
        //调用初始值has置为false,d为-1
        ArcNode *p;
        int w;
        visited[u]=1; //置已访问的标记
        d++;
        p=G->adjlist[u].firstarc; //p指向顶点u的第一个邻接点
        while(p!=NULL)
        {
            w=p->adjvex;
            if(visited[w]==0) //若顶点w未访问,则递归访问
            {
                Cycle(G,w,v,d,has); //从顶点w出发搜索
            }
            else if(w==v&&d>1) //u到v存在一条边且回路长度大于1
            {
                has=true;
                return;
            }
            p=p->nexterc; //找下个邻接点
        }
    }
    bool hasCycle(AdjGraph *G,int v) //判断连通图中是否有经过顶点v的回路
    {
        bool has=false;
        Cycle(G,v,v,-1,has); //从顶点v出发
        return has;
    }
    

    5、判断无向图是否为一棵树

    void DFS(AdjGraph *G,int v,int &vn,int &en)
    {
        //深度优先遍历图G,并求出遍历过的顶点数vn和边数en
        ArcNode *p;
        visited[v]=1;
        vn++; //遍历过的顶点数增1
        p=G->adjlist[v].firstarc;
        while(p!=NULL)
        {
            en++; //遍历过的边数增1
            if(visited[p->adjvex]==0)
            {
                DFS(G,p->adjvex,vn,en);
            }
            p=p->nextarc;
        }
    }
    bool isTree(AdjGraph *G) //判断无向图G是否为树
    {
        int vn=0,en=0,i;
        for(i=0;i<G->n;i++)
        {
            visited[i]=0;
        }
        DFS(G,1,vn,en);
        //遍历顶点为 G->n 个,遍历边数为 2(G->n-1),则为树
        if(vn==G->n&&en==2*(G->n-1))
        {
            return true;
        }
        else
        {
             return false;   
        }
    }
    

    6、源点到其余各点的最短路径

    void shortPath(AdjGraph *G,int i)
    {
        int qu[MAXV],level[MAXV];
        int fornt=0,raer=0,k,lev; //lev保存i到访问顶点的层数
        ArcNode *p;
        visited[i]=1; //i已经访问,进队
        rear++;
        qu[rear]=i;
        level[rear]=0;
        while(front!=rear) //队非空
        {
            front=(front+1)%MAXV;
            //出队
            k=qu[front];
            lev=level[front];
            if(k!=i)
            {
                printf(" 顶点%d到顶点%d的最短距离是:%d
    ",i,k,lev);
            }
            p=G->adjlist[k].firstarc; //取k的边表头指针
            while(p!=NULL) //依次搜索邻接点
            {
                if(visited[p->adjvex==0]) //未被访问过
                {
                    visited[p->adjvex]=1;
                    rear=(rear+1)%MAXV;
                    qu[rear]=p->adjvex; //访问过的邻接点进队
                    level[rear]=lev+1;
                }
                p=p->nextarc; //顶点i的下一个邻接点
            }
        }
    }
    

    7、所有路径及其长度

    int visited[MAXV];
    void findPath(AdjGraph *G,int u,int v,int path[],int d,int length)
    {
        //d表示 path 中顶点个数,初始为 0;length 表示路径长度,初始为 0
    	int w,i;
        ArcNode *p;
        //顶点u加到路径中,d增1
        path[d]=u;
        d++;
        visited[u]=1; //置已访问标记
        if(u==v&&d>0) //找到一条路径就输出
        {
            printf(" 路径长度:%d,路径:",length);
            for(i=0;i<d;i++)
            {
                printf("%2d",path[i]);
            }
    		printf("
    ");
        }
        p=G->adjlist[u].firstarc; //p指向顶点u的第一个邻接点
        while(p!=NULL)
        {
            w=p->adjvex; //w为顶点u的邻接点
            if(visited[w]==0) //w未访问,递归访问
            {
                findPath(G,w,v,path,d,p->weigth+length);
            }
            p=p->nextarc; //p指向顶点u的下一个邻接点
        }
        visited[u]=0; //重置
    }
    
  • 相关阅读:
    进入黑马day4Serlet与Tomcat
    进入黑马day3HTTP协议与tomcat协议
    进入黑马day1XML简单学习
    进入黑马day2解析xml三种方法(2)sax解析器解析
    进入黑马day3xml三种解析方法比较
    进入黑马day2解析xml三种方法(1)jaxp解析
    进入黑马day2解析xml三种方法(3)dom4j解析器
    进入黑马day1JunitTest测试
    进入黑马day1关于云计算
    系统分析入门
  • 原文地址:https://www.cnblogs.com/wangzheming35/p/13344347.html
Copyright © 2011-2022 走看看