c++ 数据结构 图 part1.邻接表的十字链表实现

 来自《大话数据结构》第七章  p274 图

效果

graph 文件

4
5
0 3
1 0
2 0
1 2
2 1

 

graph.h 

#pragma once
#include<vector>
#include<string>
using namespace std;
struct Sidetable{//边表
    int from,to;
    Sidetable *headlink,*taillink;
    Sidetable(int f,int t):from(f),to(t){
        headlink=nullptr;
        taillink=nullptr;
    }
};
struct Vertextable{//顶点表
    int data;
    Sidetable *firstin,*firstout;
    Vertextable(){
        firstin=nullptr;
        firstout=nullptr;
    }
};

class Graph{
    int _V,_E; //顶点&变
    Vertextable *_adj;//接邻表
public:
    Graph(int v);
    Graph(const string& filename);
    int V() const;
    int E() const;
    void addEdge(int v,int w);
    Vertextable adj(int v);//和v相邻的所有顶点
    Vertextable *adj();//单独获取接邻表
    string toString();//字符串表示
};

graph.cpp

#include"graph.h"
#include<fstream>
#include<iostream>
Graph::Graph(int v){    //建立固定顶点的图
    this->_V=v;     //初始化顶点个数
    this->_E=0;     //初始化边为0
    //_adj=new vector<int>[v];    //初始化*
}
Graph::Graph(const string& filename){
    //从文件读取V&E,初始化图
    fstream f;
    f.open(filename,ios::in);
    if(!f){
        std::cerr<<"can't open file"<<endl;
        exit(-1);
    }
    int V,E;
    f>>V>>E;
    this->_V=V;
    this->_E=E;
    _adj=new Vertextable[V];  //新建接邻表 
    for(int i=0;i<V;i++){
        _adj[i].data=i;
    }
    for(int i=0;i<E;i++){//将每一个边读入
        int in_vertex,out_vertex;
        f>>in_vertex>>out_vertex;//就按照格式读入
        //开始建立十字链表
        //1、首先从文件建立一个边
        Sidetable *edge=new Sidetable(in_vertex,out_vertex);//初始化一个边
        //2、查找这个边的两边端点,在顶点表中查找并且建立联系
        //查找这条边的起点,同时查找某个点,添加为“出边”
        if(!_adj[in_vertex].firstout){
            //如果某个点的出边为nullptr,就可以将这个点的出边指向刚新建的边上
            _adj[in_vertex].firstout=edge;            
        }else{
            //如果这个点已经有一条出边了,那么就往后遍历,添加到最后一个节点的headlink上
            Sidetable *p=_adj[in_vertex].firstout;
            while(p->headlink){
                p=p->headlink;
            }
            p->headlink=edge;
        }
        //查找这条边的终点,同时查找某个点,添加为“入边”
        if(!_adj[out_vertex].firstin){
            //如果某个点的入边为nullptr,则可以将这点的入边指向刚新建的边上
            _adj[out_vertex].firstin=edge;
        }else{
            //如果这个点已经有一条入边了,那么就往后遍历,添加到最后一个节点的taillink上
            Sidetable *p=_adj[out_vertex].firstin;
            while(p->taillink){
                p=p->taillink;
            }
            p->taillink=edge;
        }
    }
    f.close();//关闭文件
}
int Graph::V() const{return _V;}
int Graph::E() const{return _E;}
void Graph::addEdge(int v,int w){
    //互相添加边,在vector的头部添加
    _E++;
}
Vertextable Graph::adj(int v){  //获取某个顶点的接邻点
    return _adj[v];
}
Vertextable* Graph::adj(){  //单独获取接邻表
    return _adj;
}

main.cpp

#include<iostream>
#include<cstdio>
#include"graph.h"
using namespace std;
int main(){
    Graph g("graph");
    cout<<"build success"<<endl;
    cout<<"Vertex:"<<g.V()<<endl;
    for(int i=0;i<g.V();i++){
        printf("[%d] in:",i);
        Sidetable *p=g.adj(i).firstin;
        while(p){
            cout<<p->from<<" ";
            p=p->taillink;
        }

        printf("[%d] out:",i);
        p=g.adj(i).firstout;
        while(p){
            cout<<p->to<<" ";
            p=p->headlink;
        }
        cout<<endl;
    }
    return 0;
}

CMakeLists.txt 

aux_source_directory(. CPP_FILES)
add_executable(out ${CPP_FILES})

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值