数据结构--十字链表(相加,创建)

// CrossList.cpp : Defines the entry point for the console application.
/*-----CODE FOR FUN---------------
-------CREATED BY Dream_Whui------
-------2015-2-4-------------------*/

#include "stdafx.h"
#include <iostream>
using namespace std;

#define   TRUE                    1
#define   FALSE                    0
#define   OK                    1
#define   ERROR                    0
#define   OVERFLOW                -2
#define   INFEASIBLE            -1

#define      ElemType int

typedef struct OLNode//十字链表结点的结构
{
    int                i,j;//行,列
    ElemType        e;//结点元素值
    struct OLNode    *right, *down;//结点右边,下方的结点
}OLNode, *OLink;

typedef struct//十字链表结构
{
    OLink    *rhead, *chead;//行链表,列链表
    int        mu,nu,tu;//行数,列数,结点数
}CrossList;

int CreateCrossList(CrossList* M)//创建十字链表
{
    if(M)    
        free(M);
    M = (CrossList*)malloc(sizeof(CrossList));//分配空间
    int m,n,t;
    cin>>m>>n>>t;//行数,列数,结点数
    M->mu = m;
    M->nu = n;
    M->tu = t;
    M->rhead = (OLink*)malloc( (m+1)*sizeof(OLink) );//分配行链表空间
    M->chead = (OLink*)malloc( (n+1)*sizeof(OLink) );//分配列链表空间
    if(!M->chead || !M->rhead)
        return ERROR;
    int k;
    for(k=1; k<=m; k++)
        M->rhead[k] = NULL;//初始化行链表数组
    for(k=1; k<=n; k++)
        M->chead[k] = NULL;//初始化列链表数组
    int i,j,e;
    cin>>i>>j>>e;//结点赋值(i,j,e)三元组
    while(i != 0)
    {
        OLNode *p = (OLNode*)malloc(sizeof(OLNode));//生成临时结点
        OLNode *q;
        if(!p)
            return ERROR;
        p->i = i;//临时结点赋值
        p->j = j;
        p->e = e;
        if(M->rhead[i] == NULL || M->rhead[i]->j > j)//当临时结点在该行头结点之前或改行头结点为空
        {
            p->right = M->rhead[i];
            M->rhead[i] = p;
        }
        else
        {
            for(q=M->rhead[i]; q->right && q->right->j < j; q=q->right);//找到在临时结点之前改行的某个结点
            p->right = q->right;
            q->right = p;
        }
        if(M->chead[j] == NULL || M->chead[j]->i >i)//当临时结点在该列头结点之前或改列头结点为空
        {
            p->down = M->chead[j];
            M->chead[j] = p;
        }
        else
        {
            for(q=M->chead[j]; q->down && q->down->i < i; q=q->down);//找到在临时结点之前该列的某个结点
            p->down = q->down;
            q->down = p;
        }
        cin>>i>>j>>e;
    }
    return OK;
}

void PrintMatrix(CrossList &M)
{
    cout<<"行数:"<<M.mu<<" "<<"列数:"<<M.nu<<" "<<"非零元个数:"<<M.tu<<endl;
    int i;
    OLNode *p;
    cout<<"按行输出:"<<endl;
    for(i=1; i<=M.mu; i++)
    {
        p = M.rhead[i];
        if(!p)
        {
            cout<<"(空行)"<<endl;
            continue;
        }
        while(p)
        {
            cout<<"("<<p->i<<","<<p->j<<","<<p->e<<")"<<" ";
            p = p->right;
        }
        cout<<endl;
    }
    cout<<"按列输出"<<endl;
    for(i=1; i<=M.nu; i++)
    {
        p = M.chead[i];
        if(!p)
        {
            cout<<"(空列)"<<endl;
            continue;
        }
        while(p)
        {
            cout<<"("<<p->i<<","<<p->j<<","<<p->e<<")"<<" ";
            p = p->down;
        }
        cout<<endl;
    }
}

int AddMatrix(CrossList* A, CrossList *B)//矩阵相加
{
    if(A->mu != B->mu || A->nu != B->nu)
        return ERROR;
    if(A->tu * B->tu == 0)
        return ERROR;
    OLNode *pa, *pb, *pre, *p;
    OLink *hl = (OLink*)malloc( (A->nu+1) * sizeof(OLink));
    int i, j;
    for(j=1; j<=A->nu; j++)
        hl[j] = A->chead[j];
    for(i=1; i<=A->mu; i++)
    {
        pa = A->rhead[i];//pa指向矩阵A某行第一个非零结点
        pb = B->rhead[i];//pb指向矩阵B某行第一个非零结点
        pre = NULL;
        p = (OLNode*)malloc(sizeof(OLNode));
        while(pa || pb)
        {
            if(!pb)//当矩阵B该行没有结点,则结束循环,跳到下一行
                break;
            if(pa==NULL || pa->j > pb->j)//当矩阵A某行没有非零结点,或者矩阵B该行第一个非零结点在矩阵A之前
            {
                A->tu++;//结点数自增
                p->i = pb->i;//临时结点赋值
                p->j = pb->j;
                p->e = pb->e;
                if(pre==NULL)//行链表中插入临时结点
                    A->rhead[p->i] = p;
                else
                    pre->right = p;
                p->right = pa;
                pre = p;
                if(!A->chead[p->j] || A->chead[p->j]->i > p->i)//当矩阵A的某列没有非零结点,或者矩阵B该列第一个非零结点在矩阵A之前
                {
                    p->down = A->chead[p->j];//列链表中插入临时结点
                    A->chead[p->j] = p;
                }
                else
                {
                    p->down = hl[p->j]->down;
                    hl[p->j]->down = p;
                }
                hl[p->j] = p;
                pb = pb->right;
            }
            else if(pa !=NULL && pa->j < pb->j)//矩阵B某行某列为空
            {
                pre = pa;
                pa = pa->right;
            }
            else if(pa->j == pb->j)
            {
                pa->e += pb->e;
                if(pa->e == 0)//相加后为零,则要在行链表和列列链表中做删除操作
                {
                    A->tu--;
                    if(pre == NULL)
                        A->rhead[pa->i] = pa->right;
                    else
                    {
                        pre->right = pa->right;
                    }
                    p = pa;
                    pa = pa->right;
                    pb = pb->right;
                    if(A->chead[p->j] == p)
                        A->chead[p->j] = hl[p->j] = p->down;
                    else
                        hl[p->j]->down = p->down;
                    free(p);
                    p = (OLNode*)malloc(sizeof(OLNode));
                }
                else
                {
                    pa = pa->right;
                    pb = pb->right;
                }
            }
        }
    }
    return OK;
}

int main(int argc, char* argv[])
{
    CrossList *M = (CrossList*)malloc(sizeof(CrossList));
    CrossList *N = (CrossList*)malloc(sizeof(CrossList));
    CreateCrossList(M);
    CreateCrossList(N);
    PrintMatrix(*M);
    PrintMatrix(*N);
    AddMatrix(M,N);
    PrintMatrix(*M);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值