C++实现无向图类

C++实现无向图

本篇主要记录一下最近学习的较简单的无向图实现,主要参考了《算法》第四版中关于图的内容。

该无向图支持自环但不支持平行边,日后慢慢优化吧。

首先我们知道图是由一组顶点和一组能够将两个顶点相连的边组成。这里我们定义一个顶点类,顶点类中有该顶点的value以及该顶点的邻居顶点的集合,这个集合对应了在《算法》书中使用了bag类的对象,本篇使用C++的list类似乎也问题没那么大。最后一个成员变量是该顶点的度数,度数在无向图中可以理解为顶点的邻节点数量。下面是顶点类的定义:

class Vertex
{
public:
    Vertex(int val)
    {
        in_out = 0;
        value = val;
    };
    int value;
    int in_out;
    list<Vertex *> neighbours;
};

因为在无向图中,边只是两个顶点的连接,因此就先不给边定义一个专门的类了,用顶点类的邻居节点就可以表示出边的情况。

接下来可以利用这个顶点类来构造一个无向图类undirect_Graph了。

首先需要定义一个构造函数,这个构造函数应该可以将图这种结构表示出来,本篇还是沿用《算法》书里的方法,读取一个txt文件,该文件第一行的数字表示这个图的顶点数,第二行的数字表示这个图包含的边数,剩余每一行的数据都是成对出现,代表相连的两个顶点,如下所示:
在这里插入图片描述
读取方法如下所示:

undirect_Graph::undirect_Graph(string path)
{
    ifstream data(path);
    int dat;
    data >> dat;
    cout << "the count of Vertex : " << dat << " ";
    m_countOfVertex =dat;
    data >> dat;
    cout << "the count of Edge : " << dat << " ";
    m_countOfEdge = dat;
    cout << endl;
//    neighbourVertexs = vector<Vertex *>(m_countOfVertex);
    for(int index = 0; index < m_countOfEdge; index++)
    {
        cout << "读取顶点: " ;
        data >> dat;
        cout << dat << "   ";
        int firstVertex = dat;
        
        cout << "读取顶点: " ;
        data >> dat;
        cout << dat << endl;
        
        
        
        int secondVertex = dat;
        addEdge(firstVertex, secondVertex);
        
    }
    
}

void undirect_Graph::addEdge(int firstVertex, int secondVertex)
{
    
    Vertex *firstVertexNode = new Vertex(firstVertex);
    Vertex *secondVertexNode = new Vertex(secondVertex);
    
    firstVertexNode->neighbours.push_back(secondVertexNode);
    firstVertexNode->in_out++;
    secondVertexNode->neighbours.push_back(firstVertexNode);
    secondVertexNode->in_out++;
    
    pair<int, Vertex*> v(firstVertex, firstVertexNode);
    pair<int, Vertex*> w(secondVertex, secondVertexNode);
    if (!isInserted(firstVertex, VertexSet))
    {
        VertexSet.insert(v);
    }
    else
    {
        VertexSet[firstVertex]->neighbours.push_back(secondVertexNode);
        
    }
    if(!isInserted(secondVertex, VertexSet))
    {
        VertexSet.insert(w);
    }
    else
    {
        VertexSet[secondVertex]->neighbours.push_back(firstVertexNode);
    }
}

调用这个无向图的构造函数之后,我们可以从无向图对象中获取该图的边数、顶点数,以及顶点集合,这个顶点集合里每个顶点对象都包含有该顶点的邻居顶点集合,在搜索时就可以访问每个顶点对象中的邻居顶点了。而利用上面的测试用例,我们定义一个undirect_Graph对象后就可以得到如下图所示的一个无向图结构。

在这里插入图片描述

int main(){
    string path = "graph_initial.txt";
    undirect_Graph graph(path);
    graph.print_allVertexAndEdge();
    DepthFirstGraph dfg(graph, 0);
    cout << dfg.getCount() << endl;
    return 0;
    }

其他一些基本的图算法函数比较简单就不多赘述,如打印出图中节点与节点的连接情况等。

全部代码如下所示:

//
//  Graph_practise.hpp
//  Dat_Structure
//
//  Created by  云子谣 on 2020/4/10.
//  Copyright © 2020  云子谣. All rights reserved.
//

#ifndef Graph_practise_hpp
#define Graph_practise_hpp

#include <stdio.h>
#include <vector>
#include <iostream>
#include <string>
#include <fstream>
#include <map>
#include <set>
#include <list>
using namespace std;
#endif /* Graph_practise_hpp */

//顶点类
class Vertex
{
public:
    Vertex(int val)
    {
        in_out = 0;
        value = val;
    };
    int value;
    int in_out;
    list<Vertex *> neighbours;
};


class undirect_Graph
{
public:
    undirect_Graph(string path);
    int countOfVertex();  //获得顶点数
    int countOfEdge();  // 边数
    void addEdge(int firstVertex, int secondVertex);
    void print_allVertexAndEdge();
    map<int, Vertex*> getGraphVertexSet();
private:
    int m_countOfVertex;
    int m_countOfEdge;
    map<int, Vertex *> VertexSet;
    bool isInserted(int v, map<int, Vertex*> VertexSet);
    
//    vector<Vertex *> neighbourVertexs;
};
//
//  Graph_practise.cpp
//  Dat_Structure
//
//  Created by  云子谣 on 2020/4/10.
//  Copyright © 2020  云子谣. All rights reserved.

#include "Graph_practise.hpp"

undirect_Graph::undirect_Graph(string path)
{
    ifstream data(path);
    int dat;
    data >> dat;
    cout << "the count of Vertex : " << dat << " ";
    m_countOfVertex =dat;
    data >> dat;
    cout << "the count of Edge : " << dat << " ";
    m_countOfEdge = dat;
    cout << endl;
//    neighbourVertexs = vector<Vertex *>(m_countOfVertex);
    for(int index = 0; index < m_countOfEdge; index++)
    {
        cout << "读取顶点: " ;
        data >> dat;
        cout << dat << "   ";
        int firstVertex = dat;
        
        cout << "读取顶点: " ;
        data >> dat;
        cout << dat << endl;
        
        
        
        int secondVertex = dat;
        addEdge(firstVertex, secondVertex);
        
    }
    
}
void undirect_Graph::addEdge(int firstVertex, int secondVertex)
{
    
    Vertex *firstVertexNode = new Vertex(firstVertex);
    Vertex *secondVertexNode = new Vertex(secondVertex);
    
    firstVertexNode->neighbours.push_back(secondVertexNode);
    firstVertexNode->in_out++;
    secondVertexNode->neighbours.push_back(firstVertexNode);
    secondVertexNode->in_out++;
    
    pair<int, Vertex*> v(firstVertex, firstVertexNode);
    pair<int, Vertex*> w(secondVertex, secondVertexNode);
    if (!isInserted(firstVertex, VertexSet))
    {
        VertexSet.insert(v);
    }
    else
    {
        VertexSet[firstVertex]->neighbours.push_back(secondVertexNode);
        
    }
    if(!isInserted(secondVertex, VertexSet))
    {
        VertexSet.insert(w);
    }
    else
    {
        VertexSet[secondVertex]->neighbours.push_back(firstVertexNode);
    }
    
    
    
}
bool undirect_Graph::isInserted(int v, map<int, Vertex *> VertexSet)
{
    map<int, Vertex*>::iterator iter = VertexSet.begin();
    for(iter; iter != VertexSet.end(); iter++)
    {
        if(iter->first == v)
            return true;
    }
    return false;
}

void undirect_Graph::print_allVertexAndEdge()
{
    map<int, Vertex*>::iterator iter = VertexSet.begin();
    for(iter; iter != VertexSet.end(); iter++)
    {
        cout << "顶点" << iter->first << "的邻节点:";
        for(list<Vertex*>::iterator j = iter->second->neighbours.begin(); j != iter->second->neighbours.end(); j++)
        {
            cout << (*j)->value << " ";
        }
        cout << endl;
    }
}
map<int, Vertex*> undirect_Graph::getGraphVertexSet()
{
    return VertexSet;
}
int undirect_Graph::countOfVertex()
{
    return m_countOfVertex;
}

下篇主要是基于这个无向图记录一下深度优先搜索算法的实现过程。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值