数据结构---图(邻接表)

来源:互联网 发布:绝对领域 知乎 编辑:程序博客网 时间:2024/04/26 03:36
// Graph_Adjacency List.cpp : Defines the entry point for the console application./*-----CODE FOR FUN----------------------CREATED BY Dream_Whui-------------2015-2-12--------------------*/#include "stdafx.h"#include <iostream>#include <queue>using namespace std;#define      MAX_VERTEX_NUM    20#define   TRUE             1#define   FALSE            0#define   OK               1#define   ERROR            0#define   OVERFLOW          -2#define   INFEASIBLE      -1typedef        char*    VertexType;typedef        int        InfoType;typedef enum{    DG,DN,UDG,UDN//有向图,有向网,无向图,无向网}GraphKind;typedef struct ArcNode{        int                adjvex;        //该弧所指向的顶点的位置    struct ArcNode    *nextarc;    //指向下一条弧的指针    InfoType        *info;        //该弧相关信息的指针}ArcNode;typedef struct VNode{    VertexType        data;        //顶点信息    ArcNode            *firstarc;    //指向第一条依附该顶点的弧的指针}VNode, AdjList[MAX_VERTEX_NUM];typedef struct{    AdjList    vertices;    int        vexnum,arcnum;        //顶点数,弧数    int        kind;                //图的种类标记}ALGraph;bool visited[MAX_VERTEX_NUM];int CreateDG(ALGraph &G);//构造有向图int CreateDN(ALGraph &G);//构造有向网int CreateUDG(ALGraph &G);//构造无向图int CreateUDN(ALGraph &G);//构造无向网int CreateGraph(ALGraph &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(ALGraph G, VertexType v)    //顶点v在图中的位置{    int i;    for(i=0; i<G.vexnum; i++)    {        if(strcmp(G.vertices[i].data,v)==0)            return i;    }    return -1;}void CreateSub(ALGraph &G, int i, int j, int* w)//创建图(网)的辅助函数,构建第i个顶点到第j个顶点,权值w{    ArcNode *e, *p, *pre;    e = (ArcNode*)malloc(sizeof(ArcNode));    p = (ArcNode*)malloc(sizeof(ArcNode));    pre = (ArcNode*)malloc(sizeof(ArcNode));    e->adjvex = j;                        //    e->nextarc = NULL;    e->info = w;    if(!G.vertices[i].firstarc)            //在头结点后插入            G.vertices[i].firstarc = e;        else                                    {            p = G.vertices[i].firstarc;            if(p->adjvex < j)            //在第一个结点前插入(第一个结点指头结点后面的那个结点)            {                e->nextarc = p;                G.vertices[i].firstarc = e;            }            else                        //在第以个结点后插入            {                pre = p;                p = p->nextarc;                while(p)                {                    if(p->adjvex < j)                    {                        e->nextarc = p;                        pre->nextarc = e;                        break;                    }                    pre = p;                    p = p->nextarc;                }                if(!p)                    //在尾结点后插入                    pre->nextarc = e;            }        }}int CreateDG(ALGraph &G)//构造有向图{    cout<<"输入顶点数,边数:"<<endl;    cin>>G.vexnum>>G.arcnum;    int i,j,k,w;    for(i=0; i<G.vexnum; i++)//构造顶点向量    {        cout<<"输入第"<<i+1<<"个顶点的名称:";        G.vertices[i].data = (VertexType)malloc( sizeof(char) );        cin>>G.vertices[i].data;        G.vertices[i].firstarc = 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);//弧尾        j = LocateVex(G,v2);//弧头        w = 1;        CreateSub(G,i,j,&w);    }    G.kind = DG;    return OK;}int CreateUDG(ALGraph &G)//构造无向图{    cout<<"输入顶点数,边数:"<<endl;    cin>>G.vexnum>>G.arcnum;    int i,j,k,w;    for(i=0; i<G.vexnum; i++)//构造顶点向量    {        cout<<"输入第"<<i+1<<"个顶点的名称:";        G.vertices[i].data = (VertexType)malloc( sizeof(char) );        cin>>G.vertices[i].data;        G.vertices[i].firstarc = 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);//边的起点        j = LocateVex(G,v2);//边的终点        CreateSub(G,i,j,&w);        CreateSub(G,j,i,&w);    }    G.kind = UDG;    return OK;}int CreateDN(ALGraph &G)//构造有向网{    cout<<"输入顶点数,边数:"<<endl;    cin>>G.vexnum>>G.arcnum;    int i,j,k,w;    for(i=0; i<G.vexnum; i++)//构造顶点向量    {        cout<<"输入第"<<i+1<<"个顶点的名称:";        G.vertices[i].data = (VertexType)malloc( sizeof(char) );        cin>>G.vertices[i].data;        G.vertices[i].firstarc = NULL;    }    char *v1, *v2;    v1 = (char*)malloc(sizeof(char));    v2 = (char*)malloc(sizeof(char));    for(k=0; k<G.arcnum; k++)    {        cout<<"输入相连的边及权值(v1,v2,w):";        cin>>v1>>v2>>w;        i = LocateVex(G,v1);//弧尾        j = LocateVex(G,v2);//弧头        CreateSub(G,i,j,&w);    }    G.kind = DN;    return OK;}int CreateUDN(ALGraph &G)//构造无向网{    cout<<"输入顶点数,边数:"<<endl;    cin>>G.vexnum>>G.arcnum;    int i,j,k,w;    for(i=0; i<G.vexnum; i++)//构造顶点向量    {        cout<<"输入第"<<i+1<<"个顶点的名称:";        G.vertices[i].data = (VertexType)malloc( sizeof(char) );        cin>>G.vertices[i].data;        G.vertices[i].firstarc = NULL;    }    char *v1, *v2;    v1 = (char*)malloc(sizeof(char));    v2 = (char*)malloc(sizeof(char));    for(k=0; k<G.arcnum; k++)    {        cout<<"输入相连的边及权值(v1,v2,w):";        cin>>v1>>v2>>w;        i = LocateVex(G,v1);//边的起点        j = LocateVex(G,v2);//边的终点        CreateSub(G,i,j,&w);        CreateSub(G,j,i,&w);    }    G.kind = UDN;    return OK;}VertexType GetVex(ALGraph G, int v)//返回图中第V个顶点{    if(v<0 || v>G.vexnum)        return NULL;    return G.vertices[v-1].data;}int PutVex(ALGraph &G, VertexType v, VertexType value)//修改图中顶点v的名称为value{    int i;    i = LocateVex(G,v);    if(i<0)        return ERROR;    else        strcpy(G.vertices[i].data,value);    return OK;}ArcNode* FirstAdjVex(ALGraph G, VertexType v)//返回顶点V的第一个邻接点{    int i;    i = LocateVex(G,v);    if(i<0)        return NULL;    else        return G.vertices[i].firstarc;}ArcNode* NextAdjVex(ALGraph G, VertexType v, VertexType w)//返回顶点V的(相对于w)下一个邻接点{    int i,j,k;    i = LocateVex(G,v);    j = LocateVex(G,w);    if(i<0 || j<0)        return NULL;    ArcNode *p;    p = G.vertices[i].firstarc;    while(p)    {        if(p->adjvex == j)            return p->nextarc;        p = p->nextarc;    }}void InsertVex(ALGraph &G, VertexType v)//插入顶点{    G.vertices[G.vexnum].data = (VertexType)malloc( sizeof(char) );    strcpy(G.vertices[G.vexnum].data,v);    G.vertices[G.vexnum].firstarc = NULL;    G.vexnum++;}int DeleteVex(ALGraph &G, VertexType v)//删除顶点{    int i,k,j;    k = LocateVex(G,v);    if(G.kind < 2)//有向        j = 1;    else        //无向        j = 0;    if(v<0)        return ERROR;    ArcNode *p,*q;    p = G.vertices[k].firstarc;//p指向顶点v的链表    while(p)                    //删除顶点v的链表    {        q = p;        G.vertices[k].firstarc = p->nextarc;        p = p->nextarc;        free(q);        G.arcnum--;            //边数减1    }    for(i=0; i<G.vexnum; i++)//对邻接表其余顶点链表操作,删除有顶点v的指针    {        p = G.vertices[i].firstarc;        if(p)                    {            if(p->adjvex == k)    //删除第一个结点(顶点v是第一个结点)            {                G.vertices[i].firstarc = p->nextarc;                free(p);                G.arcnum = G.arcnum - j;            }            else                //删除第一个后的结点(顶点v不是第一个结点)            {                    q = p;                p = p->nextarc;                while(p)                {                    if(p->adjvex == k)                    {                        q->nextarc = p->nextarc;                        free(p);                        G.arcnum = G.arcnum - j;//有向:边再减1;无向:不用再减1                        break;                    }                    q = p;                    p = p->nextarc;                }            }        }    }    for(i=k; i<G.vexnum-1; i++)//邻接表第k个位置后都往前移        G.vertices[i] = G.vertices[i+1];    G.vexnum--;                    //顶点数减1    for(i=0; i<G.vexnum; i++)    //由于邻接表位置的挪动,导致各顶点链表中的adjvex域都错位,应重新调整    {        p = G.vertices[i].firstarc;        while(p)        {            if(p->adjvex > k)    //第k个位置后的链表都往前移了,因此p->adjvex > k的情况下,都减1                p->adjvex = p->adjvex -1;            p = p->nextarc;        }    }}int InsertArc(ALGraph &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)//有向        CreateSub(G,i,j,&weight);    else         //无向    {        CreateSub(G,i,j,&weight);        CreateSub(G,j,i,&weight);    }    return OK;}void DeleteSub(ALGraph &G, int i, int j)//删除边或弧的辅助函数{    ArcNode *p, *pre;    p = G.vertices[i].firstarc;    if(p->adjvex == j)    {            G.vertices[i].firstarc = p->nextarc;        free(p);    }    else    {        pre = p;        p = p->nextarc;        while(p)        {            if(p->adjvex == j)            {                pre->nextarc = p->nextarc;                free(p);                break;            }            pre = p;            p = p->nextarc;        }    }}int DeleteArc(ALGraph &G, VertexType v, VertexType w)//删除一条边{    int i,j,k;    i = LocateVex(G,v);//尾    j = LocateVex(G,w);//头    if(i<0 || j<0)        return ERROR;    if(G.kind < 2)//有向        DeleteSub(G,i,j);    else        //无向    {        DeleteSub(G,i,j);        DeleteSub(G,j,i);    }    G.arcnum--;    return OK;}void Display(ALGraph G){    int i;    ArcNode *t;    cout<<"边数:"<<G.arcnum<<endl;    cout<<"顶点数:"<<G.vexnum<<endl;    for(i=0; i<G.vexnum; i++)    {        cout<<i+1<<": "<<G.vertices[i].data;        t = G.vertices[i].firstarc;        while(t)        {            cout<<G.vertices[t->adjvex].data;            t = t->nextarc;        }        cout<<endl;    }}void Visit(VertexType e){    cout<<e;}void DFS(ALGraph G, int i){    visited[i] = TRUE;    Visit(G.vertices[i].data);    ArcNode *w;    for(w=FirstAdjVex(G,G.vertices[i].data); w!=NULL; w=NextAdjVex(G,G.vertices[i].data,G.vertices[w->adjvex].data))    {        if(!visited[w->adjvex])            DFS(G,w->adjvex);    }}void DFSTraverse(ALGraph G, void(*Visit)(VertexType))//深度优先遍历{    int i;    for(i=0; i<G.vexnum; i++)        visited[i] = FALSE;    for(i=0; i<G.vexnum; i++)    {        if(!visited[i])            DFS(G,i);    }    cout<<endl;}void BFSTraverse(ALGraph G, void(*Visit)(VertexType))//广度优先搜索算法{    int i,u;    ArcNode *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.vertices[i].data);            Q.push(i);            while(!Q.empty())            {                u = Q.front();                Q.pop();                for(w=FirstAdjVex(G,G.vertices[u].data); w!=NULL; w=NextAdjVex(G,G.vertices[u].data,G.vertices[w->adjvex].data))                {                    if(!visited[w->adjvex])                    {                        visited[w->adjvex] = TRUE;                        Visit(G.vertices[w->adjvex].data);                        Q.push(w->adjvex);                    }                }            }        }    }    cout<<endl;}int main(int argc, char* argv[]){    ALGraph G;    CreateGraph(G);    Display(G);    DFSTraverse(G,Visit);    BFSTraverse(G,Visit);    return 0;}

1 0
原创粉丝点击