[数据结构]图

来源:互联网 发布:Java返回值是特殊类型 编辑:程序博客网 时间:2024/06/10 02:50

数据结构——图

   定义: 
   图是由顶点的又穷非空集合和顶点之间边的集合,通常表示为:G(V,E),G是一个图,V是图G中顶点的集合,E是图G中边的集合。
   有向图:两顶点之间的边没有方向
   无向图:两顶点之间的边有方向
   带权的图(网):两顶点之间的连线具有权重
  图的存储结构:
  1、邻接矩阵
  图的邻接矩阵存储是用两个数组表示图,其中一个一维数组表示顶点,一个二维数组表示图中边的关系(为0表示两个顶点不相连,不为0表示两顶点之间边的权重)
  
struct Graph{    //顶点    int vertexes[MAX];    //边    int arc[MAX][MAX];    //顶点总数、边的总数    int sum_vertexes,sum_edges;};
   2、邻接表
    邻接表是数组与链表相结合来存储图:
    一个一维数组表示顶点,然后每个顶点的所有相连的顶点构成一个线性表。
   
struct graphNode{    int name;    int weight;    struct graphNode *next;};struct vertexesNode{    int name;    graphNode *firstNode;};struct Graph{    vertexesNode vertexes[MAX];    int sum_vertexes,sum_edges;};
     图的建立:
   1、邻接矩阵
<span style="font-size:12px;">//无向表void createGraph_1(Graph &graph){    cout<<"输入顶点的个数"<<endl;    cin>>graph.sum_vertexes;    cout<<"输入边的个数"<<endl;    cin>>graph.sum_edges;    for(int i=0; i<graph.sum_vertexes; i++)    {        cout<<"输入第"<<i+1<<"个顶点的标识"<<endl;        cin>>graph.vertexes[i];    }    //矩阵初始化    for(int i=0; i<graph.sum_vertexes; i++)    {        for(int j=0; j<graph.sum_vertexes; j++)        {            graph.arc[i][j]=0;        }    }    for(int i=0; i<graph.sum_edges; i++)    {        int x;        int y;        int weight;        cout<<"输入第"<<i+1<<"条边的两个定点和该边的权重"<<endl;        cin>>x>>y>>weight;        graph.arc[x][y]=graph.arc[y][x]=weight;    }}//有向表void createGraph_2(Graph &graph){    cout<<"输入顶点的个数"<<endl;    cin>>graph.sum_vertexes;    cout<<"输入边的个数"<<endl;    cin>>graph.sum_edges;    for(int i=0; i<graph.sum_vertexes; i++)    {        cout<<"输入第"<<i+1<<"个顶点的标识"<<endl;        cin>>graph.vertexes[i];    }    //矩阵初始化    for(int i=0; i<graph.sum_vertexes; i++)    {        for(int j=0; j<graph.sum_vertexes; j++)        {            graph.arc[i][j]=0;        }    }    for(int i=0; i<graph.sum_edges; i++)    {        int x;        int y;        int weight;        cout<<"输入第"<<i+1<<"条弧的弧尾 弧头 权重"<<endl;        cin>>x>>y>>weight;        graph.arc[x][y]=weight;    }}</span>

   2、邻接表
<span style="font-size:12px;">//无向图void createGraph_1(Graph &graph){    cout<<"输入图的顶点的个数"<<endl;    cin>>graph.sum_vertexes;    cout<<"输入图的边的个数"<<endl;    cin>>graph.sum_edges;    for(int i=0; i<graph.sum_vertexes; i++)    {        cout<<"输入第"<<i+1<<"个顶点的标识"<<endl;        cin>>graph.vertexes[i].name;        graph.vertexes[i].firstNode=NULL;    }    for(int i=0; i<graph.sum_edges; i++)    {        int x,y,weight;        int x_pos,y_pos;        cout<<"输入第"<<i+1<<"条边的两个顶点和权重"<<endl;        cin>>x>>y>>weight;        for(int j=0; j<graph.sum_vertexes; j++)        {            if(graph.vertexes[j].name==x)            {                x_pos=j;                break;            }        }        for(int j=0; j<graph.sum_vertexes; j++)        {            if(graph.vertexes[j].name==y)            {                y_pos=j;                break;            }        }        graphNode *temp_x=new graphNode();        temp_x->weight=weight;        temp_x->name=y;        temp_x->next=graph.vertexes[x_pos].firstNode;        graph.vertexes[x_pos].firstNode=temp_x;        graphNode *temp_y=new graphNode();        temp_y->weight=weight;        temp_y->name=x;        temp_y->next=graph.vertexes[y_pos].firstNode;        graph.vertexes[y_pos].firstNode=temp_y;    }}//有向图void createGraph_2(Graph &graph){    cout<<"输入图的顶点的个数"<<endl;    cin>>graph.sum_vertexes;    cout<<"输入图的边的个数"<<endl;    cin>>graph.sum_edges;    for(int i=0; i<graph.sum_vertexes; i++)    {        cout<<"输入第"<<i+1<<"个顶点的标识"<<endl;        cin>>graph.vertexes[i].name;        graph.vertexes[i].firstNode=NULL;    }    for(int i=0; i<graph.sum_edges; i++)    {        int x,y,weight;        int x_pos,y_pos;        cout<<"输入第"<<i+1<<"条弧的弧尾 弧首 权重"<<endl;        cin>>x>>y>>weight;        for(int j=0; j<graph.sum_vertexes; j++)        {            if(graph.vertexes[j].name==x)            {                x_pos=j;                break;            }        }        graphNode *temp_x=new graphNode();        temp_x->weight=weight;        temp_x->name=y;        temp_x->next=graph.vertexes[x_pos].firstNode;        graph.vertexes[x_pos].firstNode=temp_x;    }}</span>
      图的遍历:
    1、深度优先遍历
           a)邻接矩阵
  
<span style="font-size:12px;">void DFS(Graph graph,int i){    visited[i]=1;    //do something    cout<<graph.vertexes[i]<<endl;    for(int j=0; j<graph.sum_vertexes; j++)    {        if(graph.arc[i][j]!=0&&visited[j]==0)        {            DFS(graph,j);        }    }}void DFSTraverse(Graph graph){    for(int i=0; i<graph.sum_vertexes; i++)        visited[i]=0;    for(int i=0; i<graph.sum_vertexes; i++)        if(visited[i]==0)            DFS(graph,i);}</span>

           b)邻接表
<span style="font-size:12px;">void DFS(Graph graph,int i){    visited[i]=1;    cout<<graph.vertexes[i].name<<endl;    graphNode *node=graph.vertexes[i].firstNode;    while(node)    {        if(visited[node->name]==0)            DFS(graph,node->name);        node=node->next;    }}void DFSTraverse(Graph graph){    for(int i=0; i<graph.sum_vertexes; i++)        visited[i]=0;    for(int i=0; i<graph.sum_vertexes; i++)        if(visited[i]==0)            DFS(graph,i);}</span>


    2、宽度优先遍历
           a)邻接矩阵
<span style="font-size:12px;">oid BFSTraverse(Graph graph){    queue<int> q;    for(int i=0; i<graph.sum_vertexes; i++)        visited[i]=0;    for(int i=0; i<graph.sum_vertexes; i++)    {        if(visited[i]==0)        {            visited[i]=1;            //do something            cout<<graph.vertexes[i]<<endl;            q.push(graph.vertexes[i]);            while(!q.empty())            {                int temp=q.front();                q.pop();                for(int j=0; j<graph.sum_vertexes; j++)                {                    if(graph.arc[temp][j]!=0&&visited[j]==0)                    {                        visited[j]=1;                        //do something                        cout<<graph.vertexes[j]<<endl;                        q.push(graph.vertexes[j]);                    }                }            }        }    }}</span>

           b)邻接表
<span style="font-size:12px;">void BFSTraverse(Graph graph){    queue<int> q;    for(int i=0; i<graph.sum_vertexes; i++)        visited[i]=0;    for(int i=0; i<graph.sum_vertexes; i++)    {        if(visited[i]==0)        {            visited[i]=1;            //do something            cout<<graph.vertexes[i].name<<endl;            q.push(graph.vertexes[i].name);            while(!q.empty())            {                int temp=q.front();                q.pop();                graphNode *node=graph.vertexes[temp].firstNode;                while(node)                {                    if(visited[node->name]==0)                    {                        q.push(node->name);                        //do something                        cout<<node->name<<endl;                        visited[node->name]=1;                    }                    node=node->next;                }            }        }    }}</span>



0 0