十字链表的加法

文章详细介绍了如何创建和操作十字链表,特别是在进行加法运算时处理节点的插入、删除和值的更新。提出了先不考虑删除,后统一删除值为0的节点的策略,以及通过额外空间避免数组越界的问题。同时,通过prev指针简化首元素的特殊处理。

创建十字链表还好,主要麻烦的是加法的部分

将a作为最终输出链表,将b中元素加到a中 ,可能有三种情况

  1. 二者对应元素和为0 ,即需要删去该结点
  2. 二者之和不为0 ,继续
  3. b中元素a中没有,新插入结点

可以考虑的方法:

在加法时不考虑结点的删除 ,在全部加完之后再删除值为 0 的 结点 。这样可以有效减少复杂的分类和讨论

注意了:矩阵认为从第一行第一列开始,与数组默认从第0个元素开始不同 。因此为了减少麻烦,可以在分配的时候多分配一个空间,这样可以通过下标对应访问,即 a[i] 就是对应第 i 行/列 。

若不按照此默认规则 ,可能会导致越界 (共有 n行 ,但行下标为 0到 n-1 , 这样若输入数据含有 第n行会导致数组越界 。

由于没有额外设置头结点,因此插入和删除都要单独讨论第一个元素,为了减少麻烦,可以采用 prev 指针, prev指针随 p 指针一起移动,这样可以省去对最后一个元素的讨论

否则 p->right->value 可能会因为 p->right 是 NULL 而导致错误 ,这样的话就还要对 p 是否是最后一个元素分类 。

#include<bits/stdc++.h>
using namespace std;

struct node {
	int row, col, value;
	node* down;
	node* right;
};
struct Olink {
	int rows, cols, nodes;
	node** downlist;
	node** rightlist;
};
void setNULL(node** a, int n)
{
	node** pp = a+1;
	for (int i = 1; i <= n; i++, pp++)
		*pp = NULL;
}
void initcol(node*& a, node*& p)
{
	node* t = a;
	if (a == NULL) a = p;
	else
	{
		while (t->down != NULL)
		{
			t = t->down;
		}
		t->down = p;
	}
}
void initrow(node*& a, node*& p)   
{
	node* t = a;
	if (a == NULL)
	{
		a = p;
		return;
	}
	while (t->right != NULL)
	{
		t = t->right;
	}
	t->right = p;
}
void Init(Olink& a, int n)
{
	node* p;
	a.downlist = (node**)malloc(sizeof(node*) * (a.rows+1));
	a.rightlist = (node**)malloc(sizeof(node*) * (a.cols+1));
	setNULL(a.downlist, a.rows);
	setNULL(a.rightlist, a.cols);

	for (int i = 0; i < n; i++)
	{
		p = (node*)malloc(sizeof(node));
		cin >> p->row >> p->col >> p->value;
		p->down = NULL;
		p->right = NULL;
		initcol(a.rightlist[p->col], p);
		initrow(a.downlist[p->row], p);
	}
}
void showrow(node* a)
{
	node* p = a;
	while (p != NULL)
	{
		cout << p->row << ' ' << p->col << ' ' << p->value << endl;
		p = p->right;
	}
}
void showwhole(Olink& a)
{
	for (int i = 1; i <= a.rows; i++)
	{
		if (a.downlist[i] != NULL)
			showrow(a.downlist[i]);
	}
}
void deletenode(node* prev, node* p) 
{
	prev->right = p->right;
	free(p);
}
void deletelinenode(node*& a)
{
	node* p = a->right, * prev = a;
	if (a->value == 0)
	{
		a = a->right;
	}
	while (p != NULL)
	{
		if (a->value == 0)
		{
			a = a->right;
		}
		if (p->value == 0)
		{
			deletenode(prev, p);
			p = prev->right;
		}
		else
		{
			p = p->right;
			prev = prev->right;
		}
	}
}
void insert(node* a, node* p) 
{
	node* prev = a;
	node* t = a->right;
	while (t != NULL && t->col < p->col)
	{
		t = t->right;
		prev = prev->right;
	}
	if (t == NULL)
	{
		prev->right = p;
		return;
	}
	if (p->col == t->col)
		t->value += p->value;
	else
	{
		prev->right = p;
		p->right = t;
	}
}

void addcol(node*& a, node* b)
{
	node* pb = b, * t = pb->right;
	if (a == NULL)
	{
		a = b;
		node* pa = a;
		pb = b->right;
		while (pb != NULL)
		{
			pa->right = pb;
			pa = pb;
			pb = pb->right;
		}
		return;
	}
	if (b->col == a->col)
	{
		a->value += b->value;
	}

	else if (b->col < a->col)
	{
		b->right = a;
		a = b;
	}
	
	else  insert(a, pb);
	pb = t;
	while (pb != NULL)
	{
		t = pb->right;
		insert(a, pb);
		pb = t;
	}
}
void add(Olink& a, Olink& b)
{
	for (int i = 1; i <= a.rows; i++)
	{
		if (b.downlist[i] == NULL) continue; 
		else
		{
			addcol(a.downlist[i], b.downlist[i]);
			if (a.downlist[i] == NULL) continue;
			deletelinenode(a.downlist[i]);
		}
	}
}
int main()
{
	Olink a, b;
	cin >> a.rows >> a.cols;
	b.rows = a.rows;
	b.cols = a.cols;
	cin >> a.nodes >> b.nodes;
	Init(a, a.nodes);
	Init(b, b.nodes);
	add(a, b);
	showwhole(a);
}
稀疏矩阵是指矩阵中大部分元素为0的矩阵。为了节省存储空间和提高运算效率,可以使用稀疏矩阵的存储方式——十字链表十字链表是一种特殊的链表结构,它由行链表和列链表组成,每个节点同时属于行链表和列链表。在十字链表中,行链表和列链表的头节点分别为行头节点和列头节点,它们的数据域分别存储行号和列号。数据节点的数据域存储矩阵中的非零元素值,指针域分别指向同一行和同一列的下一个非零元素节点。 以下是Python实现稀疏矩阵十字链表的基本步骤: 1. 定义节点类,包括数据域和指针域。 2. 定义行头节点和列头节点。 3. 读入矩阵,创建数据节点,并将其插入到行链表和列链表中。 4. 实现矩阵加法、减法和乘法等运算。 具体实现细节可以参考下面的代码示例: ``` class MatNode: def __init__(self, data=0, row=0, col=0): self.data = data self.row = row self.col = col self.right = None self.down = None class SparseMatrix: def __init__(self, mat=[]): self.rows = len(mat) self.cols = len(mat[0]) self.rheads = [MatNode() for i in range(self.rows)] self.cheads = [MatNode() for i in range(self.cols)] for i in range(self.rows): for j in range(self.cols): if mat[i][j] != 0: node = MatNode(mat[i][j], i, j) self.insert(node) def insert(self, node): row, col = node.row, node.col rhead, chead = self.rheads[row], self.cheads[col] p, q = rhead, chead while p.right and p.right.col < col: p = p.right while q.down and q.down.row < row: q = q.down node.right = p.right node.down = q.down p.right = q.down = node def add(self, other): if self.rows != other.rows or self.cols != other.cols: return None res = SparseMatrix() for i in range(self.rows): p, q = self.rheads[i], other.rheads[i] while p.right and q.right: if p.right.col < q.right.col: res.insert(MatNode(p.right.data, i, p.right.col)) p = p.right elif p.right.col > q.right.col: res.insert(MatNode(q.right.data, i, q.right.col)) q = q.right else: res.insert(MatNode(p.right.data + q.right.data, i, p.right.col)) p, q = p.right, q.right while p.right: res.insert(MatNode(p.right.data, i, p.right.col)) p = p.right while q.right: res.insert(MatNode(q.right.data, i, q.right.col)) q = q.right return res def sub(self, other): if self.rows != other.rows or self.cols != other.cols: return None res = SparseMatrix() for i in range(self.rows): p, q = self.rheads[i], other.rheads[i] while p.right and q.right: if p.right.col < q.right.col: res.insert(MatNode(p.right.data, i, p.right.col)) p = p.right elif p.right.col > q.right.col: res.insert(MatNode(-q.right.data, i, q.right.col)) q = q.right else: res.insert(MatNode(p.right.data - q.right.data, i, p.right.col)) p, q = p.right, q.right while p.right: res.insert(MatNode(p.right.data, i, p.right.col)) p = p.right while q.right: res.insert(MatNode(-q.right.data, i, q.right.col)) q = q.right return res def mul(self, other): if self.cols != other.rows: return None res = SparseMatrix([[0] * other.cols for i in range(self.rows)]) for i in range(self.rows): p = self.rheads[i].right while p: j = p.col q = other.cheads[j].down while q: k = q.row res[i][k] += p.data * q.data q = q.down p = p.right return res def display(self): for i in range(self.rows): p = self.rheads[i].right for j in range(self.cols): if p and p.col == j: print(p.data, end=' ') p = p.right else: print(0, end=' ') print() # 测试代码 mat1 = [[1, 0, 0], [0, 2, 0], [0, 0, 3]] mat2 = [[4, 0, 0], [0, 5, 0], [0, 0, 6]] smat1 = SparseMatrix(mat1) smat2 = SparseMatrix(mat2) smat3 = smat1.add(smat2) smat4 = smat1.sub(smat2) smat5 = smat1.mul(smat2) smat1.display() smat2.display() smat3.display() smat4.display() smat5.display() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值