数据结构---图(数组表示法)

// MGraph_array.cpp : Defines the entry point for the console application.
/*-----CODE FOR FUN---------------
-------CREATED BY Dream_Whui------
-------2015-2-9--------------------*/

#include "stdafx.h"
#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      -1

bool 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;
}

int main(int argc, char* argv[])
{
    MGraph G;
    CreateGraph(G);
    int i,j;
    Display(G);
    for(i=0; i<G.vexnum; i++)
        cout<<"第"<<i+1<<"个顶点的名字:"<<GetVex(G,i+1)<<endl;
    cout<<endl;

    VertexType w;
    for(i=1; i<=G.vexnum; i++)
    {
        for(w=FirstAdjVex(G,G.vexs[i-1]); w!=NULL; w=NextAdjVex(G,G.vexs[i-1],w))
            cout<<w<<" ";
        cout<<endl;
    }
    DFSTraverse(G,Visit);
    BFSTraverse(G,Visit);
    //PutVex(G,"v1","v0");
    //for(i=0; i<G.vexnum; i++)
    //cout<<"第"<<i+1<<"顶点的名字:"<<GetVex(G,i+1)<<endl;
    //cout<<endl;

    //cout<<FirstAdjVex(G,G.vexs[0])<<endl;
    //cout<<NextAdjVex(G,G.vexs[0],G.vexs[1])<<endl;

    //DeleteVex(G,G.vexs[0]);
    //Display(G);

    //InsertVex(G,"A1");
    //Display(G);
    return 0;
}

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值