码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构基础 之 通过邻接矩阵与邻接表 图 实现

时间:2015-07-11 16:47:24      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:   有向图   有权图   邻接矩阵   邻接表   

【邻接矩阵】

邻接矩阵,就是一个反应边与边之间联系的二维数组。这个二维数组我们用matrix[numV][numV]表示,其中numV是顶点数。

对于无权图

若顶点Vi和Vj之间有边,则matrix[Vi][Vj]=1;否则matrix[Vi][Vj]=0。

对于有权图

若顶点Vi和Vj之间有边,且权值为weight,则matrix[Vi][Vj]=weight;否则matrix[Vi][Vj]=0或MAXWEIGHT(取最小权值或最大权值)。

【邻接表】

当图中的边数较少时,用邻接矩阵来实现图结构,则会浪费很多内存空间。因此,考虑另一种实现图结构的方法:邻接表。在邻接表中主要有两种节点结构体:

顶点节点(表示结点数据,也可以是节点下标(vertex),以及下一节点地址(next))

技术分享

边节点(表示节点数据,也可以是节点下标(vertex),节点出度表(adjvex),以及出度表中下一节点地址(next))

技术分享

【源码示例】

  • 邻接矩阵建图

void Graph::createGraph()  

{  

    cout << "输入边数 ";  

    while (cin >> numE && numE < 0)  

        cout << "输入有误!,重新输入 ";  

  

    int i, j, w;  

    if (!isWeighted)  //无权图  

    {  

        if (!isDirected)  //无向图  

        {  

            cout << "输入每条边的起点和终点:\n";  

            for (int k = 0; k < numE; k++)  

            {  

                cin >> i >> j;  

                while (!check(i, j))  

                {  

                    cout << "输入的边不对!重新输入\n";  

                    cin >> i >> j;  

                }  

                matrix[i][j] = matrix[j][i] = 1;  

            }  

        }  

        else  //有向图  

        {  

            cout << "输入每条边的起点和终点:\n";  

            for (int k = 0; k < numE; k++)  

            {  

                cin >> i >> j;  

                while (!check(i, j))  

                {  

                    cout << "输入的边不对!重新输入\n";  

                    cin >> i >> j;  

                }  

                matrix[i][j] = 1;  

            }  

        }  

    }  

    else  //有权图  

    {  

        if (!isDirected)   //无向图  

        {  

            cout << "输入每条边的起点、终点和权值:\n";  

            for (int k = 0; k < numE; k++)  

            {  

                cin >> i >> j >> w;  

                while (!check(i, j, w))  

                {  

                    cout << "输入的边不对!重新输入\n";  

                    cin >> i >> j >> w;  

                }  

                matrix[i][j] = matrix[j][i] = w;  

            }  

        }  

        else  //有向图  

        {  

            cout << "输入每条边的起点、终点和权值:\n";  

            for (int k = 0; k < numE; k++)  

            {  

                cin >> i >> j >> w;  

                while (!check(i, j, w))  

                {  

                    cout << "输入的边不对!重新输入\n";  

                    cin >> i >> j >> w;  

                }  

                matrix[i][j] = w;  

            }  

        }  

    }  

}  

  • 邻接表建图

void Graph::createGraph()  

{  

    //用一个新的变量表示边数,numE的修改则留到insertedge()中  

    int numEdge = 0;  

    cout << "输入边数 ";  

    while (cin >> numEdge && numEdge < 0)  

        cout << "输入有误!,重新输入 ";    

    int i, j, w;  

    if (!isWeighted)  //无权图  

    {  

        cout << "输入每条边的起点和终点:\n";  

        for (int k = 0; k < numEdge; k++)  

        {  

            cin >> i >> j;  

            while (!check(i, j))  

            {  

                cout << "输入的边不对!重新输入\n";  

                cin >> i >> j;  

            }  

            insertEdge(i, j);  

        }  

    }  

    else  //有权图  

    {  

        cout << "输入每条边的起点、终点和权值:\n";  

        for (int k = 0; k < numEdge; k++)  

        {  

            cin >> i >> j >> w;  

            while (!check(i, j, w))  

            {  

                cout << "输入的边不对!重新输入\n";  

                cin >> i >> j >> w;  

            }  

            insertEdge(i, j, w);  

        }  

    }  

}  

void Graph::insertEdge(int vertex, int adjvex, int weight)  

{  

    insertedge(vertex, adjvex, weight);  

    if (!isDirected)  //无向图  

        insertedge(adjvex, vertex, weight);  

}  

void Graph::insertedge(int vertex, int adjvex, int weight)  

{  

    EdgeNode *p, *q, *r;

    p = q = r = NULL;  

    if (adjList[vertex].next)   //非第一个节点  

    {  

        p = adjList[vertex].next;  

        //移动p到合适位置  

        while (p && (p->adjvex < adjvex))  

        {  

            q = p;  

            p = p->next;  

        }  

        if (p && (p->adjvex == adjvex))  //修改已有边权值  

            p->weight = weight;  

        else  

        {  

            r = new EdgeNode;  

            r->adjvex = adjvex;  

            r->weight = weight;  

            r->next = p;  

            //当加入的新节点位于表的第一个位置  

            if (adjList[vertex].next == p)  

                adjList[vertex].next = r;  

            else  

                q->next = r;  

            numE++;  

        }  

    }  

    else  

    {  

        p = new EdgeNode;  

        p->adjvex = adjvex;  

        p->weight = weight;  

        p->next = NULL;  

        adjList[vertex].next = p;  

        numE++;  

    }  

}  

【详细源码详址】

http://blog.csdn.net/zhangxiangdavaid/article/details/38321327

http://blog.csdn.net/zhangxiangdavaid/article/details/38323593

【最后的话】

很明显的发现,邻接矩阵和邻接表一个是以矩阵数组的形式记录了图中边的关系,一个是以链表的形式记录边的关系。无它,链表肯定比数据更节省空间,但是,查找起来数据往往比链表更快捷。如果,还有兴趣可以用STL的list实现,这样将尽收二者之长,鉴于实现非常简单,此处代码就不再给出。

版权声明:本文为博主原创文章,未经博主允许不得转载。

数据结构基础 之 通过邻接矩阵与邻接表 图 实现

标签:   有向图   有权图   邻接矩阵   邻接表   

原文地址:http://blog.csdn.net/u013630349/article/details/46842443

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!