#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
#include<cstdlib>
using namespace std;

#define MaxInt 32767
#define MVNum 100
bool visited[MaxInt];
typedef int VerTexType;
typedef int ArcType,OtherInfo;
typedef struct ArcNode{//边 
    int adjvex;//顶点序号 
    struct ArcNode *nextarc;//下一条边的指针 
    OtherInfo info;// 
}ArcNode;

typedef struct VNode{//顶点 
    VerTexType data;
    ArcNode *firstarc; 
}VNode,AdjList[MVNum];

typedef struct{
    AdjList vertices;
    int vexnum,arcnum;
}ALGraph;


int LocateVex(ALGraph G,int u){//图G存在,u和G中顶点有相同特征。若G中存在顶点u,则返回该顶点在图中的位置;否则返回其他信息。 
    for(int i=0;i<G.vexnum;i++){
        if(G.vertices[i].data==u){
            return i;
        }
    }
    return -1;
} 

void CreateGraph(ALGraph &G){//V是图的顶点集,VR是图中弧的集合。按V和R的定义构造图G。 
    cout<<"请输入顶点数,边数:"<<"\n";
    cin>>G.vexnum>>G.arcnum;
    cout<<"\n请输入每个顶点的值:"<<"\n"; 
    for(int i=0;i<G.vexnum;i++){
        cin>>G.vertices[i].data;
        G.vertices[i].firstarc=NULL;
    }
    cout<<"输入边:"<<"\n"; 
    for(int k=0;k<G.arcnum;k++){
        int v1,v2;
        cin>>v1>>v2;
        int i=LocateVex(G,v1);
        int j=LocateVex(G,v2);
        ArcNode *p1,*p2;
        p1=new ArcNode;
        p1->adjvex=j;
        p1->nextarc=G.vertices[i].firstarc; G.vertices[i].firstarc=p1;
        p2=new ArcNode;
        p2->adjvex=i;
        p2->nextarc=G.vertices[j].firstarc; G.vertices[j].firstarc=p2;
    }
    return;
}

void DestroyGraph(ALGraph &G){//图G存在。销毁图G。 
    ArcNode *p, *q;
    G.vexnum = 0;
    G.arcnum = 0;
    for( int i = 0; i < G.vexnum; i++ ){
        p = G.vertices[i].firstarc;
        while( p!=NULL ){
            q = p->nextarc;
            free( p );
            p = q;
        }
    }
    return;
} 

int GetVex(ALGraph G,int v){//图G存在,v是G中某个顶点。返回v的值。 
    for(int i=0;i<G.vexnum;i++){
        if(i==v){
            return G.vertices[i].data;
        }
    }
    return 0;
} 

void PutVex( ALGraph &G, VerTexType v, VerTexType value){//图G存在,v是G中某个顶点。对v赋值value。 
    for(int i=0;i<G.vexnum;i++){
        if(i==v){
            G.vertices[i].data=value;
        }
    }
    return;
} 

int FirstAdjVex( ALGraph G, VerTexType v ){//图G存在,v是G中某个顶点。返回v的第一个邻接顶点,若v在G中没有邻接顶点,则返回“空”。 
    ArcNode *p;
    int v1;
    v1 = LocateVex( G,v );
    p = G.vertices[v1].firstarc;
    if( p!=NULL )
        return p->adjvex;
    else
        return -1;
}

int NextAdjVex(ALGraph G, VerTexType v, VerTexType w){//图G存在,v是G中某个顶点,w是v的邻接顶点。 返回v的(相对于w的)下一个邻接顶点。若w是v的最后一个邻接顶点,则返回“空”。 
    ArcNode *p;
    int v1, w1;
    v1 = LocateVex( G, v );     //v1为顶点v在图G中的序号
    w1 = LocateVex( G, w );     //w1为顶点w在图G中的序号
    p = G.vertices[v1].firstarc;
    while( p!=NULL && p->adjvex != w1 )  //指针p不空且所指针表结点不是w
        p = p->nextarc;
    if( p==NULL || p->nextarc==NULL )      //没找到w或w是最后一个邻接顶点
        return -1;
    else
        return p->nextarc->adjvex;
} 

void InsertVex(ALGraph &G, VerTexType v ){//图G存在,u和G中顶点有相同特征。在图G中增添新顶点v. 
    G.vertices[G.vexnum].data = v;   //构造新顶点向量
    G.vertices[G.vexnum].firstarc = NULL;
    G.vexnum++;                              //图G的顶点数加1
    return;
} 

void DeleteVex( ALGraph &G, VerTexType v ){//图G存在,v是G中某个顶点。删除G中顶点v及其相关的弧。 
    int i, j;
    ArcNode *p, *q;
    j = LocateVex( G, v );         //j是定点v的序号
    if( j < 0 ){ //v不是图G的顶点
        return;
    }                   
    p = G.vertices[j].firstarc;    //删除以v为出度的弧或边
    while( p ){
        q = p;
        p = p->nextarc;
        free( q    );
        G.arcnum--;               //弧或边数减1
    }
    G.arcnum--;                   //顶点数减1
    for( i = j; i < G.vexnum; i++ ){//顶点v后面的顶点前移
        G.vertices[i] = G.vertices[i+1];
    }
        
    for( i = 0; i < G.vexnum; i++ ){//删除以v为入度的弧或边且必要是修改表结点的顶点位置
        p = G.vertices[i].firstarc;    //指向第1条弧或边
        while( p!=NULL ){//有弧
            if( p->adjvex == j ){
                if( p == G.vertices[i].firstarc ){//待删结点是第1个结点
                    G.vertices[i].firstarc = p->nextarc;
                    free( p );
                    p = G.vertices[i].firstarc;
                }else{
                    q->nextarc = p->nextarc;
                    free( p );
                    p = p->nextarc;
                }
            }else{
                if( p->adjvex > j ){
                    p->adjvex--; //修改表结点的顶点位置值
                } 
                q = p;
                p = p->nextarc;
            }
        }
    }
    return;
}

void InsertArc( ALGraph &G, VerTexType v, VerTexType w){//图G存在,v和w是G中两个顶点。在G中增添<v,w>,若G是无向图,则还增添对称弧<w,v>。 
    ArcNode *p;
    int w1, i, j;
    i = LocateVex( G, v);    //弧尾或边的序号
    j = LocateVex( G, w );   //弧头或边的序号
    if( i < 0 || j < 0 ){
        return;
    }
    G.arcnum++;
    p = new ArcNode;
    p->adjvex = j;
    p->nextarc = G.vertices[i].firstarc;    //插在表头
    G.vertices[i].firstarc = p;             //无向,生产另一个表结点
    return;
} 

void DeleteArc(ALGraph &G, VerTexType v, VerTexType w){//图G存在,v和w是G中两个顶点。在G中删除<v,w>,若G是无向图,则还删除对称弧<w,v>。
    ArcNode *p, *q;
    int i, j;
    i = LocateVex( G, v );          //i是定点(弧尾)的序号
    j = LocateVex( G, w );          //j是定点(弧头)的序号
    if( i < 0 || j < 0 || i == j ){
        return; 
    }
    p = G.vertices[i].firstarc;     //p指向顶点v的第一条弧尾
    while( p && p->adjvex != j ){     //p不空且所指之弧不是待删除<v,w>                  
        q = p;//p指向下一条弧
        p = p->nextarc;
    }
    if( p && p->adjvex == j ){       //找到弧<v,w>
        if( p == G.vertices[i].firstarc ){//p是指第1条弧
            G.vertices[i].firstarc = p->nextarc;  //指向下一条弧
        }else{
            q->nextarc = p->nextarc;  //指向下一条弧
        }
        free( p );                   //弧或边数减1
        G.arcnum--;
    }
    return;
}

void DFSTraverse(ALGraph G,VerTexType v){//图G存在。对图进行深度优先遍历,在遍历过程中对每个顶点访问一次。 
    cout<<v<<" ";
    visited[v]=true;
    ArcNode *p;
    p=new ArcNode;
    int vi=LocateVex(G,v);
    p=G.vertices[vi].firstarc;
    while(p!=NULL){
        int w=G.vertices[p->adjvex].data;
        if(visited[w]==0){
            DFSTraverse(G,w);
        }
        p=p->nextarc;
    }
    return;
}

void BFSTraverse(ALGraph G,VerTexType v){//图G存在。对图进行广度优先遍历,在遍历过程中对每个顶点访问一次。 
    cout<<v<<" ";
    visited[v]=true;
    queue<int>Q;
    Q.push(v);
    while(Q.empty()==0){
        int u=Q.front();
        Q.pop();
        for(int w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,G.vertices[w].data)){
            int x=G.vertices[w].data;
            if(visited[x]==0){
                cout<<x<<" ";
                visited[x]=true;
                Q.push(x);
            }
        }
    }
    return;
} 

int VertexDegree(ALGraph &G, VerTexType v){
    ArcNode *p;
    p=new ArcNode;
    for(int i=0;i<G.vexnum;i++){
        if(v==G.vertices[i].data){
            p=G.vertices[i].firstarc;
            break;
        }
    }
    int num=0;
    while(p!=NULL){
        num++;
        p=p->nextarc;
    }
    return num;
} 

int main(){
    ALGraph G;
    int v;
    
    cout<<"18软件轨道信号一班石启隆\n"; 
    CreateGraph(G);
    cout<<"对图进行广度优先遍历,输入历遍起点:"<<"\n";
    cin>>v;
    memset(visited,0,sizeof(visited));
    BFSTraverse(G,v);
    cout<<"\n对图进行深度优先遍历,输入历遍起点:"<<"\n";
    cin>>v;
    memset(visited,0,sizeof(visited));
    DFSTraverse(G,v);
    cout<<"\n求一个结点的度,输入一个结点:\n";
    cin>>v;
    cout<<"该结点的度为:\n"<<VertexDegree(G,v)<<"\n"; 
    return 0;
} 
上一篇:【随笔】安卓平台YUV数据(NV12/I420)渲染


下一篇:PAT甲级【2019年9月考题】——A1164 DijkstraSequence【30】