矩阵加法(十字交叉链表)

/*
十字交叉链表
    解决的问题:
        1:矩阵加法
        2:矩阵存储
*/

#include <iostream>
using namespace std;

typedef struct node_1{  /*创建节点结构*/
    int x,y;
    int value;
    struct node_1 *right ,*down;
}NODE_1,*LINK;
typedef struct node_2{  /*创建十字链表结构*/
    LINK* row;
    LINK* col;
    int mu,nu,tu;
}NODE_2;

void Create(int arr[][4],int mu,int nu,NODE_2* &result)
{
    if(mu <=0 || nu<=0)  return ;
    result = new NODE_2;
    result->tu = 0;
    result->row = new LINK[mu+1]; result->col = new LINK[nu+1];
    result->mu = mu ; result->nu = nu;
    NODE_1* node = NULL;
    NODE_1* q,*p;
    for(int i=0;i<mu;i++){
        result->row[i] = NULL;
    }
    for(int j=0;j<nu;j++){
        result->col[j] = NULL;
    }
    for(int i=0;i<mu;i++){
        for(int j=0;j<nu;j++){
            if(arr[i][j]){
                result->tu++;
                node = new NODE_1;
                node->x = i; node->y = j;
                node->right = NULL;
                node->down = NULL;
                node->value = arr[i][j];
                if(result->row[i] == NULL){    /*行添加*/
                    result->row[i] = node;
                }
                else{
                    for(q = result->row[i]; q->right && j>=q->right->y;q=q->right);
                    node->right = q->right;
                    q->right = node;
                }
                if(result->col[j] == NULL){    /*列添加*/
                    result->col[j] = node;
                }
                else{
                    for(p=result->col[j];p->down && i>=p->down->x; p=p->down);
                    node->down = p->down;
                    p->down = node;
                }
            }
        }
    }
}

void display_x(NODE_2* result)  /*根据行遍历*/
{
    if(result == NULL)  return ;
    NODE_1* tmp= NULL;
    for(int i=0;i<result->mu;i++){
        if(result->row[i] == NULL)  continue;
        tmp = result->row[i];
        while(tmp){
            cout<<tmp->x << " " << tmp->y << " " << tmp->value<<endl;
            tmp = tmp->right;
        }
    }
}
void display_y(NODE_2* result)  /*根据列遍历*/
{
    if(result == NULL)  return ;
    NODE_1* tmp= NULL;
    for(int i=0;i<result->nu;i++){
        if(result->col[i] == NULL)  continue;
        tmp = result->col[i];
        while(tmp){
            cout<<tmp->x << " " << tmp->y << " " << tmp->value<<endl;
            tmp = tmp->down;
        }
    }
}

void InsertNodeH(NODE_1* &Head,NODE_1 *p)
{
    if(p->y < Head->y){
        p->right = Head; Head = p;
    }
    else{
        NODE_1* tmp = Head;
        NODE_1* tmp_next = tmp->right;
        while(tmp_next){
            if(p->y < tmp_next->y){
                break;
            }
            tmp = tmp->right;
            tmp_next = tmp->right;
        }
        p->right = tmp_next;
        tmp->right = p;
    }
}

void InsertNodeL(NODE_1* &Head,NODE_1 *p)
{
    if(p->x < Head->x){
        p->down = Head; Head = p;
    }
    else{
        NODE_1* tmp = Head;
        NODE_1* tmp_next = tmp->down;
        while(tmp_next){
            if(p->x < tmp_next->x){
                break;
            }
            tmp = tmp->down;
            tmp_next = tmp->down;
        }
        p->down = tmp_next;
        tmp->down = p;
    }
}

/*实现矩阵的加法*/
NODE_2* GetSum(NODE_2* &node_a,NODE_2*  node_b)
{
    if(node_a->tu == 0 && node_b->tu)   return node_b;
    if(node_a->tu && node_b->tu == 0)   return node_a;
    if(node_a->tu == 0 && node_b->tu ==0 )  return NULL;
    NODE_1* tmp = NULL;
    NODE_1* tmp_next = NULL;
    NODE_1* p= NULL;
    NODE_1* q = NULL;
    for(int i=0;i<node_a->mu;i++){
        tmp = node_b->row[i];
        p = node_a->row[i];
        while(tmp){
            tmp_next = tmp->right;
            while(p){
                if(tmp->y == p->y){
                    /*当node_a中相应行中的节点的y等于node_a时,直接将相应的value添加到node_a上 此时不要处理列的问题*/
                    p->value += tmp->value;       /*直接加入value*/
                    p=p->right;
                    delete tmp;
                    tmp = NULL;
                    break;
                }
                else if(tmp->y < p->y){
                    InsertNodeH(node_a->row[i],tmp);    /*行插入*/
                    p = p->right;
                    InsertNodeL(node_a->col[tmp->y],tmp);  /*列插入*/
                    break;
                }
                p=p->right;
            }
            tmp = tmp_next;
        }
    }
    return node_a;
}
int main()
{
    int arr[][4] = 
        {
            {1,2,3,0},
            {2,3,4,0},
            {3,4,5,0},
            {4,5,6,0}
        };
    NODE_2 *result_1 = NULL;
    Create(arr,4,4,result_1);
    /*按照行遍历十字链表*/
    display_x(result_1);
    cout<<"---------------------我是分割线------------------------------"<<endl;
    /*按照列遍历十字链表*/
    display_y(result_1);
    cout<<"============================================================="<<endl;
    NODE_2* result_2 = NULL;
    Create(arr,4,4,result_2);
    /*按照行遍历十字链表*/
    display_x(result_2);
    cout<<"---------------------我是分割线------------------------------"<<endl;
    /*按照列遍历十字链表*/
    display_y(result_2);
    cout<<"============================================================="<<endl;
    NODE_2* result = NULL;    /*求解矩阵的加法*/
    result = GetSum(result_1,result_2);
    /*按照行遍历十字链表*/
    display_x(result);
    cout<<"---------------------我是分割线------------------------------"<<endl;
    /*按照列遍历十字链表*/
    display_y(result);
    system("pause");
    return 0;
}


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值