稀疏矩阵的十字链表存储表示

十字链表用的不多,但是面试可能会出现,故而记录一下。

十字链表节点形态:


十字链表形态:



实现:

/***************************************
稀疏矩阵的十字链表存储表示
by Rowandjj
2014/5/7
***************************************/
#include<iostream>
using namespace std;

typedef int ElemType;
typedef struct _NODE_
{
    int i,j;//行和列下标
    ElemType e;//元素值

    struct _NODE_ *pRight;
    struct _NODE_ *pDown;
}Node,*pNode;
typedef struct _CROSSLIST_
{
    pNode *RowHead,*ColHead;//行和列链表头指针向量
    int iRow,iCol,nodeCount;//矩阵行数,列数,非零元个数
}CrossList,*pCrossList;

//------------------------------------------------
void CreateCrossList(pCrossList pCrossListTemp);//创建十字链表
void PrintCrossList(pCrossList pCrossListTemp);
//------------------------------------------------

int main()
{
    CrossList c;
    CreateCrossList(&c);
    cout<<"----------------"<<endl;
    PrintCrossList(&c);
    return 0;
}

void CreateCrossList(pCrossList pCrossListTemp)
{
    //1.输入行数列数以及非零元个数
    cout<<"input row col nodesize:";
    cin>>pCrossListTemp->iRow;
    cin>>pCrossListTemp->iCol;
    cin>>pCrossListTemp->nodeCount;
    if(pCrossListTemp->nodeCount > pCrossListTemp->iRow*pCrossListTemp->iCol)
    {
        return;
    }
    //2.动态申请行和列指针数组
    pCrossListTemp->RowHead = (pNode *)malloc(sizeof(pNode)*pCrossListTemp->iRow);
    if(pCrossListTemp->RowHead == NULL)
    {
        return;
    }
    pCrossListTemp->ColHead = (pNode *)malloc(sizeof(pNode)*pCrossListTemp->iCol);
    if(pCrossListTemp->ColHead == NULL)
    {
        free(pCrossListTemp->RowHead);
        return;
    }
    //3.初始化这两个数组
    int i,j;
    for(i = 0; i < pCrossListTemp->iRow; i++)
    {
        pCrossListTemp->RowHead[i] = NULL;
    }
    for(j = 0; j < pCrossListTemp->iCol; j++)
    {
        pCrossListTemp->ColHead[j] = NULL;
    }
    //4.创建节点并连接到十字链表上
    for(i = 0; i < pCrossListTemp->nodeCount; i++)
    {
        //4.1创建节点
        pNode pNodeTemp = (pNode)malloc(sizeof(Node));
        if(pNodeTemp == NULL)
        {
            return;
        }
        cout<<"input i j e"<<endl;
        cin>>pNodeTemp->i;
        cin>>pNodeTemp->j;
        cin>>pNodeTemp->e;
        pNodeTemp->pDown = NULL;
        pNodeTemp->pRight = NULL;
        //4.2连接
        //连接行
        //如果该行并没有连接任何节点(NULL)或者该行连接的第一个节点的列值大于当前待连接的节点则直接将当前节点连接到该行第一个节点的位置
        if(pCrossListTemp->RowHead[pNodeTemp->i] == NULL || pCrossListTemp->RowHead[pNodeTemp->i]->j>pNodeTemp->j)
        {
            pNodeTemp->pRight = pCrossListTemp->RowHead[pNodeTemp->i];
            pCrossListTemp->RowHead[pNodeTemp->i] = pNodeTemp;
        }else//否则遍历该行找到合适的位置插入
        {
            pNode pNodeTravel = pCrossListTemp->RowHead[pNodeTemp->i];//指向第一个节点,从第一个节点开始遍历
            while(pNodeTravel->pRight != NULL && pNodeTravel->pRight->j < pNodeTemp->j)//遍历到前一个节点
            {
                pNodeTravel = pNodeTravel->pRight;    
            }
            //连接
            pNodeTemp->pRight = pNodeTravel->pRight;
            pNodeTravel->pRight = pNodeTemp;
        }
        //连接列,逻辑跟连接行一致
        if(pCrossListTemp->ColHead[pNodeTemp->j]==NULL || pCrossListTemp->ColHead[pNodeTemp->j]->i>pNodeTemp->i)
        {    
            pNodeTemp->pDown = pCrossListTemp->ColHead[pNodeTemp->j];
            pCrossListTemp->ColHead[pNodeTemp->j] = pNodeTemp;
        }else
        {
            pNode pNodeTravel = pCrossListTemp->ColHead[pNodeTemp->j];
            while(pNodeTravel->pDown != NULL && pNodeTravel->pDown->i < pNodeTemp->i)
            {
                pNodeTravel = pNodeTravel->pDown;
            }
            pNodeTemp->pDown = pNodeTravel->pDown;
            pNodeTravel->pDown = pNodeTemp;
        }
    }    
}
void PrintCrossList(pCrossList pCrossListTemp)
{
    int i,j;
    pNode pTemp;
    for(i = 0; i < pCrossListTemp->iRow; i++)
    {
        pTemp = pCrossListTemp->RowHead[i];
        for(j = 0; j < pCrossListTemp->iCol; j++)
        {
            if(pTemp != NULL && pTemp->j == j)
            {
                cout<<pTemp->e<<" ";
                pTemp = pTemp->pRight;
            }else
            {
                cout<<"0 ";
            }
        }
        cout<<endl;
    }
    cout<<endl;
}

测试结果:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值