十字链表完成稀疏矩阵相加

#include <iostream>
#include <malloc.h>
#include <stdio.h>

using namespace std;

typedef struct OLNode
{
    int i,j;
    int e;
    struct OLNode *right,*down;
}OLNode,*OLink;

typedef struct
{
    OLink *rhead,*chead;
    int mu,nu,tu;
}CrossList;

int CreateSMatrix_OL(CrossList &M)
{
    int i,j,k,e;
    OLink p,q,q1;
    cout<<"请分别输入该矩阵的行数,列数,所含非零元的个数:"<<endl;
    cin>>M.mu>>M.nu>>M.tu;
    if(!M.mu||!M.nu||!M.tu||M.mu*M.mu<M.tu) return 0;
    M.rhead=(OLink *)malloc((M.mu+1)*sizeof(OLink));//默认从第一行和第一列开始
    if(!M.rhead) return 0;
    M.chead=(OLink *)malloc((M.nu+1)*sizeof(OLink));
    if(!M.chead) return 0;
    for(k=1;k<=M.mu;k++) M.rhead[k]=NULL;
    for(k=1;k<=M.nu;k++) M.chead[k]=NULL;
    for(k=0;k<M.tu;k++)
    {
        cout<<"请输入当前元素在矩阵中的行号,列号,元素值:"<<endl;
        cin>>i>>j>>e;
        if(i<1||i>M.mu||j<1||j>M.nu||0==e) {cout<<"该元素输入错误!"; continue;}
        p=(OLink)malloc(sizeof(OLNode));
        p->i=i;
        p->j=j;
        p->e=e;
        //判断横行插入的位置
        if(!M.rhead[i]||M.rhead[i]->j>j)
        {
            p->right=M.rhead[i];
            M.rhead[i]=p;
        }
        else
        {
            q=M.rhead[i];
            q1=q->right;
            if(!q1) { q->right=p;p->right=NULL;}
            else
            {
                while(q1->j<j)
                {
                    q=q->right;
                    q1=q1->right;
                    if(!q1) break;
                }
                if(q1)
                {
                    q->right=p;
                    p->right=q1;
                }
                else { q->right=p;p->right=NULL;}
            }
        }
        //判断纵行插入的位置
        if(!M.chead[j]||M.chead[j]->i>i)
        {
            p->down=M.chead[j];
            M.chead[j]=p;
        }
        else
        {
            q=M.chead[j];
            q1=q->down;
            if(!q1) { q->down=p;p->down=NULL;}
            else
            {
                while(q1->i<i)
                {
                    q=q->down;
                    q1=q1->down;
                    if(!q1) break;
                }
                if(q1)
                {
                    q->down=p;
                    p->down=q1;
                }
                else { q->down=p;p->down=NULL;}
            }
        }
    }
    return 0;
}


int Display(CrossList M)
{
    int k;
    OLink p;
    for(k=1;k<=M.mu;k++)
    {
        p=M.rhead[k];
        while(p)
        {
            cout<<"("<<k<<","<<p->j<<")  "<<"e="<<p->e<<endl;
            p=p->right;
        }
    }
    cout<<endl;
    return 0;
}

int Insert(CrossList M,OLink p)//把p所指向的节点插入到十字链表中
{
    int i,j,e;
    OLink q,q1;
    i=p->i;
    j=p->j;
    e=p->e;
    if(i<1||i>M.mu||j<1||j>M.nu||0==e) cout<<"该元素插入错误!";
    if(!M.rhead[i]||M.rhead[i]->j>j)
    {
        p->right=M.rhead[i];
        M.rhead[i]=p;
    }
    else
    {
        q=M.rhead[i];
        q1=q->right;
        if(!q1) { q->right=p;p->right=NULL;}
        else
        {
            while(q1->j<j)
            {
                q=q->right;
                q1=q1->right;
                if(!q1) break;
            }
            if(q1)
            {
                q->right=p;
                p->right=q1;
            }
            else { q->right=p;p->right=NULL;}
        }
    }
    //判断纵行插入的位置
    if(!M.chead[j]||M.chead[j]->i>i)
    {
        p->down=M.chead[j];
        M.chead[j]=p;
    }
    else
    {
        q=M.chead[j];
        q1=q->down;
        if(!q1) { q->down=p;p->down=NULL;}
        else
        {
            while(q1->i<i)
            {
                q=q->down;
                q1=q1->down;
                if(!q1) break;
            }
            if(q1)
            {
                q->down=p;
                p->down=q1;
            }
            else { q->down=p;p->down=NULL;}
        }
    }
    return 0;
}


int Delete(CrossList M,OLink p)//把p所指向的节点从十字链表中删除
{
    int i,j;
    OLink q,q1;
    i=p->i;
    j=p->j;
    q=M.rhead[i];
    q1=q->right;
    if(j==q->j)
    {
        M.rhead[i]->right=q->right;
        free(q);
    }
    else
    {
        while(q1->j!=j)
        {
            q=q->right;
            q1=q1->right;
        }
        q->right=q1->right;
        free(q1);
    }
    return 0;
}


OLink IsExist(CrossList M,OLink p)//判断p所指向的节点是否存在于M十字链表中
{
    int i,j;
    OLink q;
    i=p->i;
    j=p->j;
    q=M.rhead[i];
    while(q)
    {
        if(j==q->j)  return q;
        else q=q->right;
    }
    return 0;
}


int SMatrix_Add(CrossList &M1,CrossList M2)
{
    int k;
    OLink p,pr=NULL;
    if(M1.mu!=M2.mu||M1.nu!=M2.nu) return 0;
    for(k=1;k<=M2.mu;k++)//按M2逐行进行
    {
        p=M2.rhead[k];
        while(p)//每行用指针逐个后移
        {
            pr=IsExist(M1,p);
            if(!pr) Insert(M1,p);//如果p所指向的节点在M1中不存在,则直接插入M1
            else
            {
                pr->e+=p->e;
                if(!pr->e) Delete(M1,pr);
            }
            Display(M1);
            p=p->right;
        }
    }
    return 0;
}


int main()
{
    CrossList M1,M2;
    CreateSMatrix_OL(M1);
    CreateSMatrix_OL(M2);
    Display(M1);
    Display(M2);
    SMatrix_Add(M1,M2);
    Display(M1);
    fclose(stdin);
    return 0;
}

  

转载于https://www.cnblogs.com/journal-of-xjx/p/6014110.html

上一篇:2021年年终总结和2022年展望


下一篇:单调队列模板题