十字链表——理解 通过链表储存二位数组

十字链表用通过两个结构体进行储存,第一个结构体储存 x,y坐标与记录值。
第二个结构体则存储行的头链表与列的头链表,还有关于开辟链表的大小,x,y,z,z为非零值的个数。
然后通过一个函数去实现链表的开辟,实现十字链表。
链表的两个表头为第一个结构体的指针的指针,即其指针指向第一个结构体的指针,利用第一个结构体的指针实现输入功能。
动态建立指针数组的方式如下
p = (OLink )malloc(sizeof(OLink)(m + 1)) 即开辟(m+1)个olink的空间,用p去储存olink的地址
原理图:
在这里插入图片描述

#include <iostream>
#include<iomanip>
using namespace std;
typedef struct OLNode {

	int i, j;//该非零元的行列下标
	int e;//具体数值
	struct OLNode *right , *down;//该非零元所在行表、列表的后继链域
}OLNode,*OLink;//建立一个结构,一个结构指针方便建立这个指针的数组。

typedef  struct 
{

 OLink *rhead, *chead;//行和列 链表头指针向量基址  由CreateSMatrix分配

	int mu, nu, tu;//行数,列数,非零个数
} CrossList;
void CreateSMatrix_OL(CrossList &M)
{//创建稀疏矩阵M  采用十字链表存储表示
	int m, n, t,i,j,e;
	cin >> m >> n >> t;; //输入M的行数列数和非零元个数
	M.mu = m; M.nu = n;	M.tu = t;//写入
	if (!(M.rhead = (OLink *)malloc(sizeof(OLink)*(m + 1))))exit(OVERFLOW);//建立二维指针的数组,大小为(m+1)个olink的大小的数组,同时判断是否建立成功
	if (!(M.chead = (OLink *)malloc(sizeof(OLink)*(n + 1))))exit(OVERFLOW);
	for (int i = 0; i <= m; i++)
		M.rhead[i] = NULL;//初始化表头指针为空
	for (int i = 0; i <= n; i++)
	M.chead[i] = NULL;//初始化表头指针为空指针
	for (cin>>i>>j>>e; i != 0; cout<<i<<j<<e)
	{//输入行,列,数据
		OLNode *p, *q;//建立两个储存结构的指针,方便进行写入与交换功能
		if (!(p = (OLNode *)malloc(sizeof(OLNode))))//建立一个p的空对象;
			exit(OVERFLOW);
		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)//设初始值为表头,遍历j的插入位置。
			{	
			if(q->right->j==j)
			{
			q.e=p.e;
			break;
			}
				p->right = q->right;//插入
				q->right = p;
			}
		}//完成行插入
		if (M.chead[j] == NULL || M.rhead[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)
			{
				if(q->right->i==i)
			{
			q.e=p.e;
			break;
			}
				p->down = q->down; q->down = p;//完成列插入
			}
		}
	}
	

}
int main()
{	
	CrossList a;
	CreateSMatrix_OL(a);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值