408数据结构--Grahp的代码实现

学习用,记录数据结构代码
8-13(其实是之前写的了)
图(graph)的邻接表、邻接矩阵实现以及各种操作

#include <bits/stdc++.h>
using namespace std;

#define MaxVertexNum 100
#define MaxNum 0xfffff

typedef char VertexType;
typedef int EdgeType;

struct MGraph       //邻接矩阵表示法
{
    VertexType Vex[MaxVertexNum];               //顶点集
    EdgeType Edge[MaxVertexNum][MaxVertexNum];  //边集(弧集)
    int vexnum,arcnum;
    bool digraph;                                   //1 = dirgraph ; 0 = undigraph
};

struct ArcNode          //弧集
{
    int adjvex;     //弧的终点
    struct  ArcNode *next;
    int value;
};

typedef struct Vnode    //点集
{
    VertexType data;
    ArcNode *first;
}Vnode,AdjList[MaxVertexNum];

struct ALGraph      //邻接表表示法
{
    AdjList vertices;
    int vernum,arcnum;
    bool digraph;
};
//----------------------------------------以下为Graph的邻接矩阵实现的基本操作-----------------------------------------------------------
int Locate(const MGraph &mg,const VertexType &a)
{
    int res =0;
    while(mg.Vex[res]!=a) ++res;
    if(res>=mg.vexnum) res = -1;    //数组从0开始
    return res;
}

bool Adjacent(const MGraph &mg,const VertexType &a,const VertexType &b)
{
    int i = Locate(mg,a),j=Locate(mg,b);
    if(a==-1||b==-1) return false;  
    return mg.Edge[i][j]!=0;  
}

void Neighbors(const MGraph &mg,const VertexType &a)
{
    int e = Locate(mg,a);       if(e==-1) return;
    string out1="(",out2=")";   if(mg.digraph) { out1="<"; out2=">"; }
    
    for(int i=0;i<mg.vexnum;++i)
    { 
        if(mg.Edge[i][e]!=0) cout<<out1+mg.Vex[i]+","+mg.Vex[e]+out2;
        if(mg.Edge[e][i]!=0) cout<<out1+mg.Vex[e]+","+mg.Vex[i]+out2;
    }
}

bool InsertVertex(MGraph &mg,const VertexType &a)
{
    if(mg.vexnum>=MaxVertexNum) return false;

    mg.Vex[mg.vexnum] = a;
    memset(mg.Edge[mg.vexnum],0,(MaxVertexNum-1)*sizeof(EdgeType));
    ++mg.vexnum=mg.vexnum;
    return true;
}

bool DeleteVertex(MGraph &mg,const VertexType &a)//这里不好让vernums--,因为他是数组,中间删了,nums--了,那是等于将最后一个元素给清空了啊。
{
    int e = Locate (mg,a);
    if(e==-1) return false;

    mg.Vex[e] = NULL;
    for(int i=0;i<mg.vexnum;++i)//!!没写图的弧的数目减少
    {
        mg.Edge[i][e] = 0;
        mg.Edge[e][i] = 0;
    }
        return true;
}

bool AddEdge(MGraph &mg,const VertexType &a,const VertexType &b)
{
    int i = Locate(mg,a),j = Locate(mg,b);
    if(i==-1||j==-1||mg.Edge[i][j]!=0) return false;
    if(!mg.digraph) mg.Edge[j][i]=1;
    mg.Edge[i][j]=1;
    ++mg.arcnum;
    return true;
}

bool RemoveEdge(MGraph &mg,const VertexType &a,const VertexType &b)
{
    int i = Locate(mg,a),j = Locate(mg,b);
    if(i==-1||j==-1) return false;
    if(!mg.digraph) mg.Edge[j][i] = 0;
    mg.Edge[i][j]==0;
    --mg.arcnum;
    return true;
}

int FirstNeighbor(const MGraph&mg,const VertexType &a)
{
    int e = Locate(mg,a);
    if(e==-1) return -1;
    for(int i=0;i<mg.vexnum;++i)    if(mg.Edge[e][i]!=0) return i;
    return -1;
}

int NextNeighbor(const MGraph&mg,const VertexType &a,const VertexType &b)
{
    int x = Locate(mg,a),y=Locate(mg,b);
    if(x==-1||y==-1) return -1;
    for(int i=y+1;i<mg.vexnum;++i)  if(mg.Edge[x][i]!=0) return i;
    return -1;
}
//----------------------------------------以上为Graph的邻接矩阵实现的基本操作-----------------------------------------------------------

//----------------------------------------以下为Graph的邻接表实现的基本操作-------------------------------------------------------------
int Locate(const ALGraph&alg,const VertexType &a)
{
    for(int i=0;i<alg.vernum;++i) if(a==alg.vertices[i].data) return i;
    return -1;
}

bool Adjacent(const ALGraph&alg,const VertexType &a,VertexType &b)
{
    int i = Locate(alg,a),j = Locate(alg,b);
    if(i==-1||j==-1) return false;
    for(ArcNode *p = alg.vertices[i].first;p!=NULL;p=p->next)   if(alg.vertices[p->adjvex].data==b) return true;    
    return false;
}

void Neighbors(const ALGraph&alg,const VertexType &a)
{
    int e = Locate(alg,a);      if(e==-1) return;

    string out1="(",out2=")";   if(alg.digraph) { out1="<"; out2=">"; }
    
    ArcNode *p = alg.vertices[e].first;
    while(p!=NULL)
    {
        if(alg.digraph) cout<<out1+alg.vertices[p->adjvex].data+","+a+out2;

        cout<<out1+a+","+alg.vertices[p->adjvex].data+out2;
        p=p->next;
    }
}

bool InsertVertex(ALGraph&alg,const VertexType &a)
{
    if(alg.vernum>=MaxVertexNum) return false;

    alg.vertices[alg.vernum].data=a;
    alg.vertices[alg.vernum].first=NULL;
    ++alg.vernum;
    return true;
}

bool DeleteVertex(ALGraph&alg,const VertexType &a)//这里不好让vernums--,因为他是数组,中间删了,nums--了,那是等于将最后一个元素给清空了啊。
{
    int e = Locate(alg,a);  if(e==-1) return false;
    alg.vertices[e].data=NULL;
    ArcNode*p = alg.vertices[e].first;
    ArcNode*pre = NULL;
    while(p!=NULL)
    {
        ArcNode *pt = p;
        p=p->next;
        delete pt;
       --alg.arcnum;
    }//删出度,即出去的弧
    for(int i=0;i<alg.vernum;++i)//删入度,即进入的弧
    {
        p = alg.vertices[i].first;
        while(p!=NULL)
        {
            if(alg.vertices[p->adjvex].data==a)
            {
                if(p==alg.vertices[i].first)
                {

                    alg.vertices[i].first=p->next;
                    delete p;
                    p=alg.vertices[i].first;
                    --alg.arcnum;
                } 
                else 
                {
                    pre->next=p->next;
                    delete p;
                    p=pre->next;
                    --alg.arcnum;
                }
            }
            else    
            {
                pre=p;
                p=p->next;
            }
        }
    }
    return true;
}

bool AddEdge(ALGraph&alg,const VertexType &a,const VertexType &b)//头插法
{
    int  i=Locate(alg,a),j=Locate(alg,b);  if(i==-1||j==-1) return false;
    //Adjacent(alg,a,b);//为啥子不能用????重载了不是?==参数不同,adjacent函数的参数是 const alg。 add的alg 不是const
    for(ArcNode *p = alg.vertices[i].first;p!=NULL;p=p->next)   if(alg.vertices[p->adjvex].data==b) return false; 

    ArcNode *temp = new ArcNode;
    temp->adjvex=j;
    temp->next=alg.vertices[i].first;
    alg.vertices[i].first=temp;
    ++alg.arcnum;
    return true;
}

bool RemoveEdge(ALGraph&alg,const VertexType &a,const VertexType &b)//无向图得删两条边,这里只删了一条
{
    int  i=Locate(alg,a),j=Locate(alg,b);  if(i==-1||j==-1) return false;
    //Adjacent(alg,a,b);
    ArcNode *pre=NULL;
    for(ArcNode *p = alg.vertices[i].first;p!=NULL;p=p->next)   
        {
            if(alg.vertices[p->adjvex].data==b)//遍历到了这条弧 
            {
                if(p==alg.vertices[i].first)
                {
                    alg.vertices[i].first=p->next;
                    delete p;
                    --alg.arcnum;
                }
                else
                {
                    pre->next=p->next;
                    delete p;
                    p=pre->next;
                    --alg.arcnum;
                }
                return true;
            }
            pre=p;
        }
    return false;
}

int FirstNeighbor(const ALGraph&alg,const VertexType &a)
{
    int e = Locate(alg,a);  if(e==-1) return -1;
    return alg.vertices[e].first->adjvex;
}

int NextNeighbor(const ALGraph&alg,const VertexType &a,const VertexType &b)
{
    int i=Locate(alg,a),j=Locate(alg,b);    if(i==-1||j==-1) return -1;
    for(ArcNode *p=alg.vertices[i].first;p!=NULL;p=p->next)
    {
        if(p->adjvex==j)
        {
            if(p->next==NULL) return -1;
            else return p->next->adjvex;
        }
    }
}

//----------------------------------------以上为Graph的邻接表实现的基本操作-------------------------------------------------------------
void visit(MGraph&mg,const VertexType &x){}
void visit(const MGraph&mg,const VertexType &x){}
void visit(ALGraph&alg,const VertexType &x){}
void visit(const ALGraph&alg,const VertexType &x){}
//----------------------------------------以下为Graph的邻接矩阵实现的遍历操作-----------------------------------------------------------
void BFS(const MGraph&mg,const int &x,bool visited[])
{
    queue<int> qv;    qv.push(x);
    while(!qv.empty())
    {
        int i=qv.front(); qv.pop();
        visit(mg,i);    visited[i]=true;
        for(int j=FirstNeighbor(mg,i);j>=0;j=NextNeighbor(mg,i,j))
            if(mg.Edge[i][j]!=0&&!visited[j]) qv.push(j);//因为顶点是顺序存放的,所以删除空间不好删,就设置为NULL了。
    } 
}

void DFS(const MGraph&mg,const int &x,bool visited[])//不是干到底才访问,而是访问路径是干到底。(这鸡掰算法竟然是递归的,就这?)
{
    visit(mg,x);    visited[x]=true;
    for(VertexType w=FirstNeighbor(mg,x);w>=0;w=NextNeighbor(mg,x,w))
        if(!visited[w]&&mg.Vex[w]!=NULL) DFS(mg,w,visited);
}

void BFS_DFS_Travel(const MGraph&mg)//也可用来控制大的DFS
{
    bool visited[MaxVertexNum];
    memset(visited,0,sizeof(visited));
    for(int i=0;i<mg.vexnum;++i)
    {
        if(!visited[i]&&mg.Vex[i]!=NULL) BFS(mg,i,visited);//DFS(mg,i,visited);
    }
}

//----------------------------------------以上为Graph的邻接矩阵实现的遍历操作-----------------------------------------------------------
//                                               (BFS+DFS)
//----------------------------------------以下为Graph的邻接表实现的遍历操作-------------------------------------------------------------
void BFS(const ALGraph&alg,const int &x,bool visited[])
{    
    queue<int>qv;    qv.push(x);
    while(!qv.empty())
    {
        int i=qv.front(); qv.pop();
        visit(alg,i);   visited[i]=true;   
        for(int j=FirstNeighbor(alg,i);j>=0;j=NextNeighbor(alg,i,j))
            if(!visited[j]&&alg.vertices[j].data!=NULL) qv.push(j);//因为顶点是顺序存放的,所以删除空间不好删,就设置为NULL了。
    }
}

void DFS(const ALGraph&alg,const int &x,bool visited[])//不是干到底才访问,而是访问路径是干到底。(这鸡掰算法竟然是递归的,就这?)
{
    visit(alg,x);    visited[x]=true;
    for(VertexType w=FirstNeighbor(alg,x);w>=0;w=NextNeighbor(alg,x,w))
        if(!visited[w]&&alg.vertices[w].data!=NULL) DFS(alg,w,visited);
}

void BFS_DFS_Travel(const ALGraph&alg)//也可用来控制大的DFS
{
    bool visited[MaxVertexNum];
    memset(visited,0,sizeof(visited));
    for(int i=0;i<alg.vernum;++i)
    {
        if(!visited[i]&&alg.vertices[i].data!=NULL) BFS(alg,i,visited);//DFS(mg,i,visited);
    }
}
//----------------------------------------以上为Graph的邻接表实现的遍历操作-------------------------------------------------------------

void BFS_Min_Distance(const MGraph&mg,const int &u)//最短路径。
{
    int  d[MaxVertexNum];   memset(d,MaxNum,sizeof(d));
    bool visited[MaxNum];   memset(visited,0,sizeof(visited));
    int i=u;    d[i]=0;
    queue<int> qi;  qi.push(i);   
    while(!qi.empty())
    {
        i=qi.front(); qi.pop();   visited[i];
        for(int w=FirstNeighbor(mg,i);w>=0;w=NextNeighbor(mg,i,w))
            if(!visited[w]) 
            {
                d[w]=d[i]+1;
                qi.push(w);
            }   
    }
}

最后每天一句祝我上岸中山大学!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值