图的学习--邻接矩阵和邻接表建立图

1 图的大类定义

template<class TypeOfVer,class TypeOfEdge>//边的个数即邻接矩阵中有元素的个数
class graph{
public:
    virtual void insert(TypeOfVer x,TypeOfVer y,TypeOfEdge w)=0;//w有权重,在结点x,y之间插入一条边
    virtual void remove(TypeOfVer x,TypeOfVer y)=0;//在结点x,y之间删除一条边
    virtual bool exist(TypeOfVer x,TypeOfVer y)const=0;//结点x,y之间是否存在一条边
    int numOfVer()const{return Vers;}//返回结点的数量
    int numOfEdge()const{return Edges;}//返回边的数量
    
protected:
    int Vers,Edges;}

2 图的顺序存储–用邻接矩阵储存图

包括为图增加或者减少边,判断两个结点间有没有边的存在

//顺序存储
template<class TypeOfVer,class TypeOfEdge>
class adjMatrixGraph:public graph<TypeOfVer,TypeOfEdge>{
public:
    adjMatrixGraph(int vSize,const TypeOfVer d[],const TypeOfEdge noEdgeFlag);
   //继承一些接口
    void insert(TypeOfVer x,TypeOfVer y,TypeOfEdge w);//w有权重,在结点x,y之间插入一条边
    void remove(TypeOfVer x,TypeOfVer y);//在结点x,y之间删除一条边
     bool exist(TypeOfVer x,TypeOfVer y)const;//结点x,y之间是否存在一条边
     ~adjMatrixGraph();
private:
    TyprOfEdge **edge;//在二维数组中存放邻接矩阵
    TypeOfVer *ver;//存放结点值,位置i存放第i个结点
    TypeOfEdge noEdge;//邻接矩阵中无穷大的表示值,表示这两个结点间无连接
    
    int find(TypeOfVer v)const{//返回结点名字叫v的下标
        for(int i=0;i<Vers;i++) if(ver[i]==v) return i;
    }//这里有两个东西,一个是存放结点值的数组,一个是邻接矩阵
    
}
template<class TypeOfVer,class TypeOfEdge>
adjMatrixGraph<TypeOfVer,TypeOfEdge>::adjMatrixGraph
(int vSize,const TypeOfVer d[],TypeOfEdge noEdgeFlag)
{
    int i,j;
    Vers=vSize;//结点数量
    Edges=0;//边的数量
    noEdge=noEdgeFlag;
    //存放结点的数组初始化
    ver=new TypeOfVer[vSize];
    for(int i=0;i<Vers;i++) ver[i]=d[i];
    //邻接矩阵初始化
    edge=new TypeOfEdge*[vSize];
    for(i=0;i<Vers;i++)
    {
        edge[i]=new TypeOfEdge[vSize];
        for(j=0;j<vSize;j++) edge[i][j]=noEdge;
    }
}
template<class TypeOfVer,class TypeOfEdge>
adjMatrixGraph<TypeOfVer,TypeOfEdge>;;~adjMatrixGraph()
{
    delete[]ver;
    for(int i=0;i<Vers;i++) delete[]edge[i];
    delete[]edge;
    
}
template<class TypeOfVer,class TypeOfEdge>
void adjMatrixGraph<TypeOfVer,TypeOfEdge>::
    insert(TypeOfVer x,TypeOfVer y,TypeOfEdge w)
    {
        int u=find(x),v=find(x);//找到x,y下标
        edge[u][v]=w;
        ++Edges;
    }
template<class TypeOfVer,class TypeOfEdge>
void adjMatrixGraph<TypeOfVer,TypeOfEdge>::
    remove(TypeOfVer x,TypeOfVer y)
    {
        int u-find(x),v=find(y);
        edge[u][v]=noEdge;
        --Edges;
    }
template<class TypeOfVer,class TypeOfEdge>
bool adjMatrixGraph<TypeOfVer,TypeOfEdge>::
    exist(TypeOfVer x,TypeOfVer y)const
    {
        int u=find(x),v=find(y);
        if(edge[u][v]!=noEdge) return true;
        else return false;
    }

此处检索两个结点之间有无边和边权重时,只需要看A[i][j]时间复杂度为O[1]
但图的空间复杂度比较高,因为一般图的存储比较稀疏,空间复杂度为O[n**2],因此之后换成邻接表非常有必要。

3 图的链式存储–邻接表

//图的链式存储--邻接表
template<class TypeOfVer,class TypeOfEdge>
class adjListGraph:public graph<TypeOfVer,TypeOfEdge>
{
public:
    adjListGraph(int vSize,const TypeOfVer d[]);
    //继承一些接口
    void insert(TypeOfVer x,TypeOfVer y,TypeOfEdge w);//w有权重,在结点x,y之间插入一条边
    void remove(TypeOfVer x,TypeOfVer y);//在结点x,y之间删除一条边
    bool exist(TypeOfVer x,TypeOfVer y)const;//结点x,y之间是否存在一条边
    ~adjListGraph();
private:
    struct edgeNode     //邻接表中存储边的结点类,挂在结点上的单链表
    {
        int end;//终点编号
        TypeOfEdge weight;
        edgeNode*next;
        edgeNode(int e,TypeOfEdge w,edgeNode*n=NULL)
        {
            end=e;
            weight=w;
            next=n;
        }
    };
    struct verNode
    {
        TypeOfVer ver;//结点的值
        edgeNode*head;//边表表头,单链表表头
        verNode(edgeNode*h=NULL)
        {
            head=h;
        }
    };
    verNode*verList;//唯一属性,结点表的数组
    int find(TypeOfVer v)const{
    for(int i=0;i<Vers;i++)
        if(verList[i].ver==v) return i;
    }
}
 template<class TypeOfVer,class TypeOfEdge>
adjListGraph<TypeOfVer,TypeOfEdge>::adjListGraph(int vSize,const TypeOfVer d[])
{
    Vers=vSize;
    Edges=0;
    verList=new verNode[vSize];
    for(int i=0;i<Vers;i++) verList[i]=d[i];//将传入数字赋值进对应结点表
    //以上是结点表的初始化
}
template<class TypeOfVer,class TypeOfEdge>
adjListGraph<TypeOfVer,TypeOfEdge>::~adjListGraph
{
    edgeNode*p;
    for(int i=0;i<Vers;i++)
    {
        while(verNode[i].head!=NULL)
        {
            p=verNode[i].head;
            verNode[i].head=p->next;
            delete p;
            
        }//在每个位置上删除单链表
    }
    delete[]verList;
}
template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::insert(TypeOdVer x,TypeOfVer y,TypeOfEdge w)
{
    int u=find(x),v=find(y);
    verList[u].head=new edgeNode(v,w,verList[u].head);//插到表头
    ++Edges;
}
template<class TypeOfVer,class TypeOfEdge>
void adjListGraph<TypeOfVer,TypeOfEdge>::remove(TypeOfVer x,TypeOfVer y)
{
    int u=find(x),v=find(y);
    edgeNode*p=verList[u].head;
    if(p==NULL) return;
    //如果单链表第一个结点就是被删除的
    if(p->end==v) 
    {
        verList[u].head=p->next;
        delete p;
        return;
    }
    //如果单链表中间有被删除元素
    while(p->next!=NULL&&p->next->end!=v)
    {
        p=p->next;
    }
    //让p停在对应结点前一个
    edgeVer*q;
    q=p->next;
    p->next=q->next;
    delete q;
    --Edges;
    
}
template<class TypeOfVer,class TypeOfEdge>
bool adjListGraph<TypeOfVer,TypeOfEdge>::exist(TypeOfVer x,TypeOfVer y)
{
    int u=find(x),v=find(y);
    edgeNode*p=verList[u].head;
    while(p->end!=v)
    {
        p=p->next;
        if(p==NULL) return false;
    }
    return true;
}

关键还是一些单链表的操作,如删除一个结点时,指针停在上一个结点

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值