数据结构---图的连通性

来源:互联网 发布:绝对领域 知乎 编辑:程序博客网 时间:2024/03/29 00:15
//头文件//以数组形式构造图#pragma once#include <iostream>#include <queue>using namespace std;#define        INFINITY        INT_MAX#define        NAX_VERTEX_NUM    20#define        VRtype            int//#define        InfoType        char*#define        VertexType        char*#define   TRUE             1#define   FALSE            0#define   OK               1#define   ERROR            0#define   OVERFLOW          -2#define   INFEASIBLE      -1bool visited[NAX_VERTEX_NUM];void(*VisitFunc)(VertexType);typedef enum{    DG,DN,UDG,UDN//有向图,有向网,无向图,无向网}GraphKind;typedef struct ArcCell{    VRtype        adj;//无权图,用0或1;带权图,即权值    //InfoType    *info;    }ArcCell, AdjMatrix[NAX_VERTEX_NUM][NAX_VERTEX_NUM];typedef struct //定义图的结构{    VertexType    vexs[NAX_VERTEX_NUM];//顶点向量    AdjMatrix    arcs;                 //邻接矩阵    int            vexnum,arcnum;         //定点数,边(弧)数    GraphKind    kind;                 //图的种类标记}MGraph;int CreateDG(MGraph &G);//构造有向图int CreateDN(MGraph &G);//构造有向网int CreateUDG(MGraph &G);//构造无向图int CreateUDN(MGraph &G);//构造无向网int CreateGraph(MGraph &G)//采用数组(邻接矩阵)表示法,构造图G{    int n;    cout<<"创建有向图(0),有向网(1),无向图(2),无向网(3)"<<endl;    cin>>n;    switch(n)    {    case DG:        G.kind = DG;        return CreateDG(G);//有向图    case DN:        G.kind = DN;        return CreateDN(G);//有向网    case UDG:        G.kind = UDG;        return CreateUDG(G);//无向图    case UDN:        G.kind = UDN;        return CreateUDN(G);//无向网    default:        return ERROR;    }}int LocateVex(MGraph G, VertexType V)//顶点V在图中的位置{    int i;    for(i=0; i<G.vexnum; i++)    {        if(strcmp(G.vexs[i],V) == 0)            return i;    }    return -1;//不存在,返回-1}int CreateUDG(MGraph &G)//构造无向图{    cout<<"输入顶点数,边数:"<<endl;    cin>>G.vexnum>>G.arcnum;    int i,j,k;    for(i=0; i<G.vexnum; i++)//构造顶点向量    {        cout<<"输入第"<<i+1<<"个顶点的名称:";        G.vexs[i] = (VertexType)malloc( sizeof(char) );        cin>>G.vexs[i];    }    for(i=0; i<G.vexnum; i++)//初始化领接矩阵    {        for(j=0; j<G.vexnum; j++)        {            G.arcs[i][j].adj = 0;            //G.arcs[i][j].info = NULL;        }    }    char *v1, *v2;    v1 = (char*)malloc(sizeof(char));    v2 = (char*)malloc(sizeof(char));    for(k=0; k<G.arcnum; k++)//构造邻接矩阵    {        cout<<"输入相连的边(v1,v2):";        cin>>v1>>v2;        i = LocateVex(G,v1);//定位顶点v1及v2在图中的位置        j = LocateVex(G,v2);        G.arcs[i][j].adj = 1;//权值        G.arcs[j][i] = G.arcs[i][j];//无向图中,邻接矩阵对称    }    G.kind = UDG;//无向图    return OK;}int CreateDG(MGraph &G)//构造有向图{    cout<<"输入顶点数,边数:"<<endl;    cin>>G.vexnum>>G.arcnum;    int i,j,k;    for(i=0; i<G.vexnum; i++)//构造顶点向量    {        cout<<"输入第"<<i+1<<"个顶点的名称:";        G.vexs[i] = (VertexType)malloc( sizeof(char) );        cin>>G.vexs[i];    }    for(i=0; i<G.vexnum; i++)//初始化领接矩阵    {        for(j=0; j<G.vexnum; j++)        {            G.arcs[i][j].adj = 0;            //G.arcs[i][j].info = NULL;        }    }    char *v1, *v2;    v1 = (char*)malloc(sizeof(char));    v2 = (char*)malloc(sizeof(char));    for(k=0; k<G.arcnum; k++)//构造邻接矩阵    {        cout<<"输入连接的边(v1,v2):";        cin>>v1>>v2;        i = LocateVex(G,v1);//定位顶点v1及v2在图中的位置        j = LocateVex(G,v2);        G.arcs[i][j].adj = 1;//权值    }    G.kind = DG;//有向图    return OK;}int CreateUDN(MGraph &G)//采用数组(邻接矩阵)表示法,构造无向网{    //int IncInfo;    cout<<"输入顶点数,边数:"<<endl;    cin>>G.vexnum>>G.arcnum;    int i,j,k;    for(i=0; i<G.vexnum; i++)//构造顶点向量    {        cout<<"输入第"<<i+1<<"个顶点的名称:";        G.vexs[i] = (VertexType)malloc( sizeof(char) );        cin>>G.vexs[i];    }    for(i=0; i<G.vexnum; i++)//初始化领接矩阵    {        for(j=0; j<G.vexnum; j++)        {            G.arcs[i][j].adj = INFINITY;            //G.arcs[i][j].info = NULL;        }    }    char *v1, *v2;    v1 = (char*)malloc(sizeof(char));    v2 = (char*)malloc(sizeof(char));    int w;    for(k=0; k<G.arcnum; k++)//构造邻接矩阵    {        cout<<"输入边及其权重(v1,v2,w):";        cin>>v1>>v2>>w;        i = LocateVex(G,v1);//定位顶点v1及v2在图中的位置        j = LocateVex(G,v2);        G.arcs[i][j].adj = w;//权值        G.arcs[j][i] = G.arcs[i][j];//无向网中,邻接矩阵对称    }    G.kind = UDN;//无向网    return OK;}int CreateDN(MGraph &G)//采用数组(邻接矩阵)表示法,构造有向网{    //int IncInfo;    cout<<"输入顶点数,边数:"<<endl;    cin>>G.vexnum>>G.arcnum;    int i,j,k;    for(i=0; i<G.vexnum; i++)//构造顶点向量    {        cout<<"输入第"<<i+1<<"个顶点的名称:";        G.vexs[i] = (VertexType)malloc( sizeof(char) );        cin>>G.vexs[i];    }    for(i=0; i<G.vexnum; i++)//初始化领接矩阵    {        for(j=0; j<G.vexnum; j++)        {            G.arcs[i][j].adj = INFINITY;            //G.arcs[i][j].info = NULL;        }    }    char *v1, *v2;    v1 = (char*)malloc(sizeof(char));    v2 = (char*)malloc(sizeof(char));    int w;    for(k=0; k<G.arcnum; k++)//构造邻接矩阵    {        cout<<"输入边及其权重(v1,v2,w):";        cin>>v1>>v2>>w;        i = LocateVex(G,v1);//定位顶点v1及v2在图中的位置        j = LocateVex(G,v2);        G.arcs[i][j].adj = w;//权值    }    G.kind = DN;//有向网    return OK;}VertexType GetVex(MGraph G, int v)//返回图中第V个顶点{    if(v<1 || v>G.vexnum)        return NULL;    else        return G.vexs[v-1];//顶点数组以标号0开始}int PutVex(MGraph &G, VertexType v, VertexType value)//修改图中顶点v的名称为value{    int i = LocateVex(G,v);    if(i<0)        return ERROR;    else        strcpy(G.vexs[i],value);    return OK;}VertexType FirstAdjVex(MGraph G, VertexType v)//返回顶点V的第一个邻接点{    int i,j,k;    k = LocateVex(G,v);//定位顶点v在图中的位置    if(k<0)        return NULL;    if(G.kind % 2 == 1)//网        j = INFINITY;    else        j = 0;//图    for(i=0; i<G.vexnum; i++)    {        if(G.arcs[k][i].adj != j)//邻接矩阵中该行第一个不为j的分量所在的列号            return GetVex(G,i+1);    }    return NULL;}VertexType NextAdjVex(MGraph G, VertexType v, VertexType w)//返回顶点V的(相对于w)下一个邻接点{    int i,j,k,p;    i = LocateVex(G,v);    j = LocateVex(G,w);    if(i<0 || j<0)        return NULL;    if(G.kind % 2 == 1)//网        k = INFINITY;    else        k = 0;//图    for(p=j+1; p<G.vexnum; p++)    {        if(G.arcs[i][p].adj != k)            return GetVex(G,p+1);    }    return NULL;}void InsertVex(MGraph &G, VertexType v)//插入顶点{    int j,i;    if(G.kind % 2 == 1)        j = INFINITY;//网    else        j = 0;//图    G.vexs[G.vexnum] = (VertexType)malloc(sizeof(VertexType));    strcpy(G.vexs[G.vexnum],v);    for(i=0; i<=G.vexnum; i++)        G.arcs[G.vexnum][i].adj = G.arcs[i][G.vexnum].adj = j;//初始化权值    G.vexnum++;}int DeleteVex(MGraph &G, VertexType v)//删除顶点{    int i,j,k,p;    k = LocateVex(G,v);    if(k<0)        return ERROR;    if(G.kind % 2 == 1)        j = INFINITY;//网    else        j = 0;//图    for(i=0; i<G.vexnum; i++)//入弧(出度)        if(G.arcs[k][i].adj != j)            G.arcnum--;        if(G.kind < 2)//有向        for(i=0; i<G.vexnum; i++)            if(G.arcs[i][k].adj != j)                G.arcnum--;    for(i=k+1; i<G.vexnum; i++)//顶点向量第k个之后的都往前移        strcpy(G.vexs[i-1],G.vexs[i]);    //free(G.vexs[i-1]);    G.vexs[i-1] = NULL;    for(i=0; i<G.vexnum; i++)//邻接矩阵中每行从第k列之后的都往前移    {        for(p=k+1; p<G.vexnum; p++)            G.arcs[i][p-1] = G.arcs[i][p];        G.arcs[i][p-1].adj = j;    }    G.arcs[i-1][p-1].adj = j;    for(i=k+1; i<G.vexnum; i++)//邻接矩阵中每列从第k行之后的都往上移    {        for(p=0; p<G.vexnum-1; p++)        {    G.arcs[i-1][p] = G.arcs[i][p];            if(i == G.vexnum-1)                G.arcs[i][p].adj = j;        }    }    G.vexnum--;    return OK;}int InsertArc(MGraph &G, VertexType v, VertexType w)//插入一条边或弧{    int i,j,weight;    i = LocateVex(G,v);//尾    j = LocateVex(G,w);//头    if(i<0 || j<0)        return ERROR;    G.arcnum++;    if(G.kind % 2 == 1)    {          cout<<"输入权值:";        cin>>weight;    }    else        weight = 1;    if(G.kind < 2)//有向        G.arcs[i][j].adj = weight;    else//无向        G.arcs[j][i].adj= G.arcs[i][j].adj=weight;    return OK;}int DeleteArc(MGraph &G, VertexType v, VertexType w)//删除一条边{    int i,j,weight;    i = LocateVex(G,v);//尾    j = LocateVex(G,w);//头    if(i<0 || j<0)        return ERROR;    G.arcnum--;    if(G.kind % 2 == 1)//网        weight = INFINITY;    else//图        weight = 1;    if(G.kind < 2)//有向        G.arcs[i][j].adj = weight;    else        G.arcs[i][j].adj = G.arcs[j][i].adj = weight;    return OK;}void Display(MGraph G)//输出邻接矩阵{    int i,j;    for(i=0; i<G.vexnum; i++)    {        for(j=0; j<G.vexnum; j++)        {            cout<<"("<<G.vexs[i]<<"->"<<G.vexs[j]<<",";            if(G.arcs[i][j].adj == INFINITY)                cout<<"oo";            else                cout<<G.arcs[i][j].adj;            cout<<")"<<" ";        }        cout<<endl;    }}void Visit(VertexType e){    cout<<e;}void DFS(MGraph G, int v){    visited[v] = TRUE;//访问第v个结点    VisitFunc(G.vexs[v]);    VertexType w;    for(w=FirstAdjVex(G,G.vexs[v]); w!=NULL; w=NextAdjVex(G,G.vexs[v],w) )//对第v个顶点尚未访问的邻接结点w递归调用DFS    {        if(!visited[LocateVex(G,w)])            DFS(G,LocateVex(G,w));    }}void DFSTraverse(MGraph G, void(*Visit)(VertexType))//深度优先遍历{    int v;    VisitFunc = Visit;    for(v=0; v<G.vexnum; v++)        visited[v] = FALSE;//访问标志数组    for(v=0; v<G.vexnum; v++)        if(!visited[v])//对尚未访问的顶点调用DFS            DFS(G,v);    cout<<endl;}void BFSTraverse(MGraph G, void(*Visit)(VertexType))//广度优先搜索算法{    int i,u;    VertexType w;    for(i=0; i<G.vexnum; i++)//访问标记数组初始化        visited[i] = FALSE;    queue<int> Q;            //置空的辅助队列    for(i=0; i<G.vexnum; i++)    {        if(!visited[i])        {            visited[i] = TRUE;            Visit(G.vexs[i]);            Q.push(i);            while(!Q.empty())            {                u = Q.front();//对头元素出队并置为u                Q.pop();                for(w=FirstAdjVex(G,G.vexs[u]); w!=NULL; w=NextAdjVex(G,G.vexs[u],w))                {                                    //w为u的尚未访问的邻接顶点                    if(!visited[LocateVex(G,w)])                    {                        visited[LocateVex(G,w)] = TRUE;                        Visit(w);                        Q.push(LocateVex(G,w));                    }                }            }        }    }    cout<<endl;}// Graph_Connectivity.cpp : Defines the entry point for the console application./*-----CODE FOR FUN----------------------CREATED BY Dream_Whui-------------2015-2-11--------------------*///求无向图G的深度优先生成森林,孩子兄弟链表T#include "stdafx.h"#include "Graph.h"  //引入图的头文件typedef char*    Elemtype;typedef struct CSNode//树的存储结构:孩子兄弟链表结构{    Elemtype        data;    struct CSNode    *firstchild, *nextsibling;}CSNode, *CSTree;void DFSTree(MGraph G, int i, CSTree &T)//从第i个顶点出发深度优先遍历图G,建立以T为根的生成树{    int first;    VertexType w;    CSTree p,q;    visited[i] = TRUE;    first = TRUE;    for(w=FirstAdjVex(G,G.vexs[i]); w!=NULL; w=NextAdjVex(G,G.vexs[i],w))    {        if(!visited[LocateVex(G,w)])        {            p = (CSTree)malloc(sizeof(CSNode));//分配孩子结点,并赋值            p->data = (Elemtype)malloc(sizeof(char));            p->data = w;            p->firstchild = NULL;            p->nextsibling = NULL;            if(first)                        //w是v的第一个未被访问的邻接顶点            {                T->firstchild = p;                first = FALSE;            }            else                q->nextsibling = p;            //是上一个邻接顶点的右兄弟结点            q = p;            DFSTree(G,LocateVex(G,w),q);    //从第w个顶点出发深度优先遍历图G,建立子生成树q        }    }}void DFSForest(MGraph G, CSTree &T)//无向图G的深度优先生成森林,孩子兄弟链表T{    T = NULL;    CSTree p,q;    int i;    for(i=0; i<G.vexnum; i++)        visited[i] = FALSE;    for(i=0; i<G.vexnum; i++)    {        if(!visited[i])                //第i个结点为新的生成树的根结点        {            p = (CSTree)malloc(sizeof(CSNode));//分配根结点,并赋值            p->data = (Elemtype)malloc(sizeof(char));            p->data = GetVex(G,i+1);//返回第i+1个顶点的名字(i以0起,即结点以i+1起)            p->firstchild = NULL;            p->nextsibling = NULL;            if(!T)                T = p;                //第一颗生成树的根            else                q->nextsibling = p;//是其他生成树的根(前一颗的根的“兄弟”)            q = p;                    //q指示当前生成树的根            DFSTree(G,i,p);        }    }}void DFS_Traverse(CSTree T)    //深度优先输出各顶点的名字{    if(T)    {        cout<<T->data;        DFS_Traverse(T->firstchild);        DFS_Traverse(T->nextsibling);    }}int main(int argc, char* argv[]){    MGraph G;    CSTree T;    CreateGraph(G);    DFSForest(G,T);    DFS_Traverse(T);    return 0;}

0 0
原创粉丝点击