对于有向图,为便于计算出度、入度,可采用十字链表存储;对于无向图,如果采用邻接表存储,会浪费一倍边的空间,而且在增加边、删除边时也要分别进行两次操作,为避免这些问题,可采用邻接多重表存储方式。

十字链表和邻接多重表_十字链表是什么的存储结构_十字链表

邻接多重表是参照十字链表思想对无向图的一种存储方式。理解的关键点在于边结点存储的两个端点没有头尾顺序,谁先谁后没有影响,唯一要注意的是某个端点要与连接该端点的下一条边的指针相对应(这两个是牢牢捆绑在一起的!!!),由于边结点上述的特点,所以在删除边的操作时会比较麻烦一些。

十字链表是什么的存储结构_十字链表_十字链表和邻接多重表

定义顶点结点:

struct VerNode{
    int num;
    EdgeNode* fstarc;
    VerNode(int n=-1,EdgeNode* fa=NULL)
            :num(n),fstarc(fa){}
};

定义边结点:

struct EdgeNode{
    int ivex;
    EdgeNode* ilink;
    int jvex;
    EdgeNode* jlink;
    int info;
    EdgeNode(int i=-1,EdgeNode* il=NULL,int j=-1,EdgeNode* jl=NULL,int wg=0)
            :ivex(i),ilink(il),jvex(j),jlink(jl),info(wg){}
};

增加边的操作:

bool addEdge(int iv,int jv,int val){
//数据输入非法,退出
    if(iv>=VerNum||iv=VerNum||jvivex+temp->jvex)==(iv+jv)) {
            return false;
        }
        else{
            if(temp->ivex==iv)
                temp=temp->ilink;
            else
                temp=temp->jlink;
        }
    }
//在边表头部插入 
    EdgeNode* edge=new EdgeNode(iv,NULL,jv,NULL,val);
    if(vn[iv].fstarc==NULL){
        vn[iv].fstarc=edge;
    }
    else{
        edge->ilink=vn[iv].fstarc;
        vn[iv].fstarc=edge;
    }
//同时也要更新另一个端点的链表,也是头插
    if(vn[jv].fstarc==NULL){
        vn[jv].fstarc=edge;
    }
    else{
        edge->jlink=vn[jv].fstarc;
        vn[jv].fstarc=edge;
    }
    return true;
}

删除边的操作:

bool delEdge(int iv,int jv){
//数据输入非法,退出
    if(iv>=VerNum||iv=VerNum||jvivex+iedge->jvex)==(iv+jv)){
//此处,iv可能存储在ivex中,也可能存储在jvex中,与输入边时的端点顺序有关
        if(iedge->ivex==iv)
            vn[iv].fstarc=iedge->ilink;
        else
            vn[iv].fstarc=iedge->jlink;
    }
    else{
//如果不是链表的头,则找到该点,并更新前驱结点iv对应的指针域
        while(iedge!=NULL){
            if((iedge->ivex+iedge->jvex)==(iv+jv))
                break;
            itemp=iedge;
            if(iedge->ivex==iv)
                iedge=iedge->ilink;
            else
                iedge=iedge->jlink;
        }
        if(iedge==NULL)
            return false;
        else{
            if(iedge->ivex==iv){
                if(itemp->ivex==iv)
                    itemp->ilink=iedge->ilink;
                else
                    itemp->jlink=iedge->ilink;
            }
            else{
                if(itemp->ivex==iv)
                    itemp->ilink=iedge->jlink;
                else
                    itemp->jlink=iedge->jlink;
            }
        }
    }
//对另一个端点,同样判断是否是边链表的头
    if(vn[jv].fstarc==iedge){
        if(iedge->ivex==jv)
            vn[jv].fstarc=iedge->ilink;
        else
            vn[jv].fstarc=iedge->jlink;
    }
//不是边链表的头,则找到该点,从上两段代码可知,此边结点肯定存在
    else{
        while(jedge!=iedge){
            jtemp=jedge;
            if(jedge->ivex==jv)
                jedge=jedge->ilink;
            else
                jedge=jedge->jlink;
        }
        if(jedge->ivex==jv){
            if(jtemp->ivex==jv)
                jtemp->ilink=jedge->ilink;
            else
                jtemp->jlink=jedge->ilink;
        }
        else{
            if(jtemp->ivex==jv)
                jtemp->ilink=jedge->jlink;
            else
                jtemp->jlink=jedge->jlink;
        }
    }
    delete jedge;
    return true;
}

邻接多重表删除边的操作非常麻烦,涉及到头结点的判断、边结点的查找、指针域的判断更新等,所以面对这种情况时,建议先理清思路,画出流程图,完善细节信息,再根据流程图一步步写出代码,可避免思路的混乱。

参考代码:

#include 
using namespace std;
const int VerNum=5;
bool addEdge(int iv,int jv,int val);
bool delEdge(int iv,int jv);
struct EdgeNode{
    int ivex;
    EdgeNode* ilink;
    int jvex;
    EdgeNode* jlink;
    int info;
    EdgeNode(int i=-1,EdgeNode* il=NULL,int j=-1,EdgeNode* jl=NULL,int wg=0)
            :ivex(i),ilink(il),jvex(j),jlink(jl),info(wg){}
};
struct VerNode{
    int num;
    EdgeNode* fstarc;
    VerNode(int n=-1,EdgeNode* fa=NULL)
            :num(n),fstarc(fa){}
};
VerNode vn[VerNum];
int main(){
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
    for(int i=0;i<VerNum;i++)
        vn[i].num=i;
    for(int i=0;i>iv>>jv>>val;
        addEdge(iv,jv,val);
    }
    addEdge(3,4,10);
    delEdge(0,3);
    for(int i=0;i<VerNum;i++){
        EdgeNode* p=vn[i].fstarc;
        while(p!=NULL){
            cout<ivex<<""<jvex<<"  val:"<info<ivex==i)
                p=p->ilink;
            else
                p=p->jlink;
        }
        cout<<"--------------------"<=VerNum||iv=VerNum||jvivex+temp->jvex)==(iv+jv)) {
            return false;
        }
        else{
            if(temp->ivex==iv)
                temp=temp->ilink;
            else
                temp=temp->jlink;
        }
    }
    EdgeNode* edge=new EdgeNode(iv,NULL,jv,NULL,val);
    if(vn[iv].fstarc==NULL){
        vn[iv].fstarc=edge;
    }
    else{
        edge->ilink=vn[iv].fstarc;
        vn[iv].fstarc=edge;
    }
    if(vn[jv].fstarc==NULL){
        vn[jv].fstarc=edge;
    }
    else{
        edge->jlink=vn[jv].fstarc;
        vn[jv].fstarc=edge;
    }
    return true;
}
bool delEdge(int iv,int jv){
    if(iv>=VerNum||iv=VerNum||jvivex+iedge->jvex)==(iv+jv)){
        if(iedge->ivex==iv)
            vn[iv].fstarc=iedge->ilink;
        else
            vn[iv].fstarc=iedge->jlink;
    }
    else{
        while(iedge!=NULL){
            if((iedge->ivex+iedge->jvex)==(iv+jv))
                break;
            itemp=iedge;
            if(iedge->ivex==iv)
                iedge=iedge->ilink;
            else
                iedge=iedge->jlink;
        }
        if(iedge==NULL)
            return false;
        else{
            if(iedge->ivex==iv){
                if(itemp->ivex==iv)
                    itemp->ilink=iedge->ilink;
                else
                    itemp->jlink=iedge->ilink;
            }
            else{
                if(itemp->ivex==iv)
                    itemp->ilink=iedge->jlink;
                else
                    itemp->jlink=iedge->jlink;
            }
        }
    }
    if(vn[jv].fstarc==iedge){
        if(iedge->ivex==jv)
            vn[jv].fstarc=iedge->ilink;
        else
            vn[jv].fstarc=iedge->jlink;
    }
    else{
        while(jedge!=iedge){
            jtemp=jedge;
            if(jedge->ivex==jv)
                jedge=jedge->ilink;
            else
                jedge=jedge->jlink;
        }
        if(jedge->ivex==jv){
            if(jtemp->ivex==jv)
                jtemp->ilink=jedge->ilink;
            else
                jtemp->jlink=jedge->ilink;
        }
        else{
            if(jtemp->ivex==jv)
                jtemp->ilink=jedge->jlink;
            else
                jtemp->jlink=jedge->jlink;
        }
    }
    delete jedge;
    return true;
}

———END———
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,永久会员只需109元,全站资源免费下载 点击查看详情
站 长 微 信: nanadh666

声明:1、本内容转载于网络,版权归原作者所有!2、本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。3、本内容若侵犯到你的版权利益,请联系我们,会尽快给予删除处理!