图的邻接表完整ADT设计

  • 为了方便,把写好的邻接表ADT放在这里,以备不时之需
  • 给学弟学妹们参考
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
template<class TypeOfEdge>
struct edgeNode{
    
    
    int data;
    TypeOfEdge weight;
    edgeNode<TypeOfEdge> *next;
    edgeNode(const int &d, edgeNode<TypeOfEdge> *ptr = NULL) {
    
    //构造函数,用于构造其他结点(无权图) 
    //函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面
        next = ptr;
        data = d;
    }
    edgeNode(const int &d, const TypeOfEdge &w, edgeNode<TypeOfEdge> *ptr = NULL){
    
     //构造函数,用于构造其他结点(带权图) 
    //函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面
        next = ptr;
        data = d;
        weight = w;
    }
    edgeNode(){
    
    }
    int getData(){
    
     return data;}  //取得结点的序号(顶点集) 
    TypeOfEdge getWeight(){
    
     return weight;}  //取得边集中对应边的权值 
    void SetLink( edgeNode<TypeOfEdge> *link ){
    
     next = link; }  //修改结点的next域 
    void SetData( int value ){
    
     data = value; }   //修改结点的序号(顶点集) 
    void SetWeight(TypeOfEdge value ){
    
     weight = value; }   //修改边集中对应边的权值   
};
//图的邻接表类
template<class TypeOfVer, class TypeOfEdge>
struct verNode{
    
    
    TypeOfVer ver;
    edgeNode<TypeOfEdge> *head;
    verNode(edgeNode<TypeOfEdge> *h = NULL){
    
    head = h;} 
    TypeOfVer getVer(){
    
     return ver;}  //取得结点值(顶点集) 
    edgeNode<TypeOfEdge> getHead(){
    
     return head;}  //取得对应的边表的头指针 
    void setVer(TypeOfVer value){
    
     ver = value;}  //设置结点值(顶点集) 
    void setHead(edgeNode<TypeOfEdge> value){
    
     head = value;}  //设置对应的边表的头指针
};
template <class TypeOfVer, class TypeOfEdge>
class adjlist_graph{
    
    
    private:
       int Vers;           //顶点数 
       int Edges;          //边数 
       verNode<TypeOfVer,TypeOfEdge> *verList;
       string GraphKind;     //图的种类标志 
       bool Delete_Edge( int u, int v ); 
       bool DFS(int u, int &num, int visited[]); //DFS遍历(递归部分)
       bool CheckRoute(int u, int v, int visited[]);
    public:
       adjlist_graph( const string &kd, int vSize, const TypeOfVer d[]); //构造函数构造一个只有结点没有边的图。 
       adjlist_graph( const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e); 构造函数构造一个无权图。5个参数的含义:图的类型、结点数、边数、结点集和边集 
       adjlist_graph( const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e, const TypeOfEdge w[]); //构造函数构造一个有权图。
       bool GraphisEmpty() {
    
     return Vers == 0; }  //判断图空否
       string GetGraphKind(){
    
     return GraphKind; }
       bool GetVer(int u, TypeOfVer &data); //取得G中指定顶点的值 
       int GetFirstAdjVex(int u, int &v); //返回G中指定顶点u的第一个邻接顶点的位序(顶点集)。若顶点在G中没有邻接顶点,则返回-1
       int GetNextAdjVex(int u, int v, int &w); //返回G中指定顶点u的下一个邻接顶点(相对于v)的位序(顶点集)。若顶点在G中没有邻接顶点,则返回false
       bool PutVer(int u, TypeOfVer data); //对G中指定顶点赋值 
       bool InsertVer(const TypeOfVer &data); //往G中添加一个顶点 
       int LocateVer(TypeOfVer data); //返回G中指定顶点的位置 
       bool ExistEdge(int u, int v);
       bool PrintVer();  //输出顶点集 
       bool PrintAdjList();  //输出邻接矩阵
       bool GetWeight(int u,int v,int &w);
       int Get_Degree(int u);//出度
       int Get_InDegree(int u);//入度
       bool CheckRoute(int u, int v);
       bool TopSort();//拓扑排序
       bool U_Judge_Cir();//判断无向图是否有环
       bool isDAG();//有向无环图
       bool TopSort(int &num, int topsort[]);//拓扑排序
       int GetVerNum(){
    
     return Vers;}    //取得当前顶点数 
       int GetEdgeNum(){
    
     return Edges;}  //取得当前边数 
       bool Insert_Edge(int u, int v); //无权图插入一条边
       bool Insert_Edge(int u, int v, TypeOfEdge w); //有权图插入一条边
       bool DeleteVer(const int u); //往G中删除一个顶点 
       bool DeleteEdge( int u, int v ); //删除边 (外壳:有向(删除1条边), 无向(删除2条边))
       void DFS_Traverse(int u); //DFS遍历(外壳部分)
       void BFS_Traverse(int u); //BFS遍历
       ~adjlist_graph(); //析构函数 
       bool Get_CriticalPath(int ve[], int vl[],int topSort[]);
};
//构造函数构造一个只有结点没有边的图。
template<class TypeOfVer,class TypeOfEdge>
adjlist_graph<TypeOfVer,TypeOfEdge>::adjlist_graph(const string &kd, int vSize, const TypeOfVer d[]){
    
    
    GraphKind = kd;
    Vers = vSize;
    Edges = 0;
    verList = new verNode<TypeOfVer,TypeOfEdge>[vSize];
    for(int i=0;i<vSize;i++) verList[i].ver = d[i];
}
//构造函数构造一个无权图。5个参数的含义:图的类型、结点数、边数、结点集和边集 
template<class TypeOfVer,class TypeOfEdge>
adjlist_graph<TypeOfVer,TypeOfEdge>::adjlist_graph(const string&kd, int vSize, int eSize, const TypeOfVer d[], int** e){
    
    
    GraphKind = kd;
    Vers = vSize;
    Edges = eSize;
    verList = new verNode<TypeOfVer,TypeOfEdge>[vSize];
    if(GraphKind == "UDG"||GraphKind == "DG"){
    
    
        for(int i=0; i<vSize; i++) verList[i].ver = d[i];
        for(int i=0; i<eSize; i++){
    
    
            int u = e[i][0];
            int v = e[i][1];
            verList[u].head = new edgeNode<TypeOfEdge>(v,verList[u].head);
            if(GraphKind == "UDG") verList[v].head = new edgeNode<TypeOfEdge>(u,verList[v].head);
        }
    }
}
//构造函数构造一个有权图。
template<class TypeOfVer,class TypeOfEdge>
adjlist_graph<TypeOfVer,TypeOfEdge>::adjlist_graph(const string &kd, int vSize, int eSize, const TypeOfVer d[], int **e, const TypeOfEdge w[]){
    
    
    GraphKind = kd;
    Vers = vSize;
    Edges = eSize;
    verList = new verNode<TypeOfVer,TypeOfEdge>[vSize];
    if(GraphKind == "UDN"||GraphKind == "DN"){
    
    
        for(int i=0; i<vSize; i++){
    
    
            verList[i].ver = d[i];
        }for(int i=0; i<eSize; i++){
    
    
            int u = e[i][0];
            int v = e[i][1];
            verList[u].head = new edgeNode<TypeOfEdge>(v,w[i],verList[u].head);
            if(GraphKind == "UDN") verList[v].head = new edgeNode<TypeOfEdge>(u,w[i],verList[v].head);
        }
    }
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::InsertVer(const TypeOfVer &data){
    
    
    verNode<TypeOfVer,TypeOfEdge>* new_verlist =new verNode<TypeOfVer, TypeOfEdge>[Vers+1];
    for(int i=0;i<Vers;i++){
    
    
        new_verlist[i].ver = verList[i].ver;
        new_verlist[i].head = verList[i].head;
    }
    new_verlist[Vers].ver = data;
    new_verlist[Vers].head = NULL;
    delete[] verList;
    Vers++;
    verList = new_verlist;
    return true;
}
template<class TypeOfVer,class TypeOfEdge>
int adjlist_graph<TypeOfVer,TypeOfEdge>::LocateVer(TypeOfVer data){
    
    
    for(int i=0; i<Vers; i++){
    
    
        if(data == verList[i].ver) return i;
    }
    return -1;
}
template<class TypeOfVer, class TypeOfEdge>
bool adjlist_graph<TypeOfVer, TypeOfEdge>::ExistEdge(int u, int v){
    
    
    if(u<0||v<0||u>=Vers||v>=Vers) return false;
    if(u == v) return false;
    edgeNode<TypeOfEdge> *p;
    p = verList[u].head;
    if(!p) return false;
    while(p&&p->data!=v) p=p->next;
    if(p == NULL) return false;
    return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::Delete_Edge(int u, int v){
    
    //删除单条边
    if(u<0||v<0||u>=Vers||v>=Vers) return false;
    if(!ExistEdge(u,v)) return false;
    edgeNode<TypeOfEdge> *p,*q;
    p = verList[u].head;
    if(p->data == v){
    
    
        verList[u].head = p->next;
        delete p;
        Edges--;
        return true;
    }
    while(p->next&&p->next->data!=v) p=p->next;
    q = p->next;
    p->next = q->next;
    delete q;
    Edges--;
    return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::DeleteEdge(int u,int v){
    
    
    if(GraphKind == "DG"||GraphKind == "DN"){
    
    
        if(Delete_Edge(u,v)) return true;
        return false;
    }
    if(GraphKind == "UDG"||GraphKind == "UDN"){
    
    
        if(Delete_Edge(u,v)&&Delete_Edge(v,u)){
    
    
            Edges++;
            return true;
        }
        return false;
    }
    return false;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::DeleteVer(const int u){
    
    
    edgeNode<TypeOfEdge> *p,*q;
    if(u<0||u>=Vers) return false;
    p=verList[u].head;
    for(int i=0;i<Vers;i++){
    
    
        if(i!=u) {
    
    
            DeleteEdge(i,u);
            p = verList[i].head;
            while(p){
    
    
                if(p->data > u) p->data--;
                p=p->next;
            }
        }else{
    
    
            if(GraphKind == "DG"||GraphKind == "DN"){
    
    
                p = verList[i].head;
                while(p){
    
    
                    q = p->next;
                    Edges--;
                    delete p;
                    p = q;
                }
            }
        }
    }
    for(int j=u+1;j<Vers;j++) verList[j-1] = verList[j];
    Vers--;
    return true;
}
//DFS遍历(外壳部分)
template<class TypeOfVer,class TypeOfEdge>
void adjlist_graph<TypeOfVer,TypeOfEdge>::DFS_Traverse(int u){
    
    
    int *vis = new int[Vers];
    for(int i=0;i<Vers;i++) vis[i] = 0;
    DFS(u,u,vis);
}
int f = 1;
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::DFS(int u, int &num, int *visited){
    
    
    edgeNode<TypeOfEdge> *p;
    p = verList[u].head;
    if(!visited[u]) {
    
    
        if(f == 0) cout<<"->";f = 0;
        cout<<verList[u].ver;
        visited[u] = 1;
        while(p){
    
    
            DFS(p->data,num,visited);
            p=p->next;
        }
    }
}
template<class TypeOfVer,class TypeOfEdge>
void adjlist_graph<TypeOfVer,TypeOfEdge>::BFS_Traverse(int u){
    
    
    int *vis = new int[Vers];
    for(int i=0;i<Vers;i++) vis[i] = 0;
    queue<int> q;
    edgeNode<TypeOfEdge> *p;
    q.push(u);
    while(!q.empty()){
    
    
        int v = q.front();
        if(!vis[v]){
    
    
            p = verList[v].head;
            while(p){
    
    
                q.push(p->data);
                p=p->next;
            }if(f==0) cout<<"->";f = 0;
            cout<<verList[v].ver;
        }
        vis[v] = 1;
        q.pop();
    }
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::CheckRoute(int u,int v){
    
    
    int *vis = new int[Vers];
    for(int i=0;i<Vers;i++) vis[i] = 0;
    CheckRoute(u,v,vis);
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::CheckRoute(int u,int vv,int vis[]){
    
    
    queue<int> q;
    edgeNode<TypeOfEdge> *p;
    q.push(u);
    while(!q.empty()){
    
    
        int v = q.front();
        if(!vis[v]){
    
    
            p = verList[v].head;
            while(p){
    
    
                q.push(p->data);
                p=p->next;
            }
        }
        vis[v] = 1;
        if(v == vv) return true;
        q.pop();
    }
    return false;
}
template<class TypeOfVer, class TypeOfEdge>
bool adjlist_graph<TypeOfVer, TypeOfEdge>::GetWeight(int u, int v, int &w){
    
    
    edgeNode<TypeOfEdge> *p;
    if(u<0||v<0||u>Vers||v>Vers) return false;
    p = verList[u].head;
    while(p){
    
    
        if(p->data == v){
    
    
            w = p->weight;
            return true;
        }
        p=p->next;
    }p = verList[v].head;
    while(p){
    
    
        if(p->data == u){
    
    
            w = p->weight;
            return true;
        }
        p=p->next;
    }
    return false;
}
template<class TypeOfVer,class TypeOfEdge>
int adjlist_graph<TypeOfVer,TypeOfEdge>::Get_Degree(int u){
    
    
    int ans = 0;
    edgeNode<TypeOfEdge> *p;
    p = verList[u].head;
    while(p){
    
    
        ans++;
        p=p->next;
    }
    if(ans!=0) return ans;
    return -1;
}
template<class TypeOfVer,class TypeOfEdge>
int adjlist_graph<TypeOfVer, TypeOfEdge>::Get_InDegree(int u){
    
    
    if(GraphKind == "UDG"||GraphKind == "UDN") return -1;
    int ans = 0;
    edgeNode<TypeOfEdge> *p;
    for(int i=0;i<Vers;i++){
    
    
        if(i!=u){
    
    
            p = verList[i].head;
            while(p){
    
    
                if(p->data == u) ans++;
                p=p->next;
            }
        }
    }
    if(ans!=0) return ans;
    return -1;
}
template<class TypeOfVer,class TypeOfEdge>
int adjlist_graph<TypeOfVer,TypeOfEdge>::GetFirstAdjVex(int u, int &v){
    
    
    edgeNode<TypeOfEdge> *q;
    q = verList[u].head;
    while(q){
    
    
        return q->data;
    }
    return -1;
}
template<class TypeOfVer,class TypeOfEdge>
int adjlist_graph<TypeOfVer,TypeOfEdge>::GetNextAdjVex(int u, int v, int &w){
    
    
    edgeNode<TypeOfEdge> *q;
    q = verList[u].head;
    while(q){
    
    
        if(q->data == v){
    
    
            if(!q->next) return -1;
            return q->next->data;
        }q=q->next;
    }
    return -1;
}
//无权图插入一条边
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::Insert_Edge(int u, int v){
    
    
    if(ExistEdge(u,v)) return false;
    edgeNode<TypeOfEdge> *q,*p,*r;
    q = verList[u].head;
    Edges++;
    if(!q){
    
    
        q = new edgeNode<TypeOfEdge>;
        q->data = v;
        q->next = NULL;
    }else{
    
    
        p = q;
        r = new edgeNode<TypeOfEdge>;
        r->data = v;
        q = r;
        q->next = p;
    }verList[u].head = q;
    return true;
}
//有权图插入一条边
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::Insert_Edge(int u, int v, TypeOfEdge w){
    
    
    if(u<0||v<0||u>=Vers||v>=Vers) return false;
    if(ExistEdge(u,v)) return false;
    if(GraphKind == "UDN"){
    
    
        verList[u].head = new edgeNode<TypeOfEdge>(v,w,verList[u].head);
        verList[v].head = new edgeNode<TypeOfEdge>(u,w,verList[v].head);
        Edges++;
    }if(GraphKind == "DN"){
    
    
        verList[u].head = new edgeNode<TypeOfEdge>(v,w,verList[u].head);
        Edges++;
    }
    return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::PrintVer(){
    
    
    if(Vers == 0) return false;
    for(int i=0;i<Vers;i++){
    
    
        if(i) cout<<" ";
        cout<<verList[i].ver;
    }
    cout<<endl;
    return true;
}
template<class TypeOfVer,class TypeOfEdge>
bool adjlist_graph<TypeOfVer,TypeOfEdge>::PrintAdjList(){
    
    
    if(Vers == 0) return false;
    edgeNode<TypeOfEdge> *p;
    for(int i=0;i<Vers;i++){
    
    
        p = verList[i].head;
        cout<<verList[i].ver;
        if(p) cout<<"->";
        while(p){
    
    
            if(GraphKind == "DG"||GraphKind == "UDG") cout<<p->data;
            else cout<<p->data<<'('<<p->weight<<')';
            p=p->next;
            if(p) cout<<"->";
        }
        cout<<endl;
    }
}
template<class TypeOfVer,class TypeOfEdge>
adjlist_graph<TypeOfVer,TypeOfEdge>::~adjlist_graph(){
    
    
    edgeNode<TypeOfEdge> *p;
    for(int i=0;i<Vers;i++){
    
    
        if((p = verList[i].head)){
    
    
            verList[i].head = p->next;
            delete p;
        }
    }
    delete [] verList;
}

猜你喜欢

转载自blog.csdn.net/roadtohacker/article/details/112131781