其他分享
首页 > 其他分享> > 矩阵及其十字链表结构

矩阵及其十字链表结构

作者:互联网

//一个非零元的结构
typedef struct OLNode
{
	int i,j;//非零元所在行数,列数
	ElemType e;//非零元元素值
	struct OLNode *right, *down;//该非零元所在行表和列表的后继链域
}OLNode, *OLink;
//一个稀疏矩阵的十字链表结构
typedef struct
{
	OLink *rhead, *chead;//行列链表的头指针向量,头节点
	int mu, nu, tu;//稀疏矩阵的行数,列数,非零元个数
}CrossList;
Status CreateCrossMatrix(CrossList &M)
{
	if(M)
	{
		free(M);
	}
	scanf(&M.mu, &M.nu, &M.tu);
	if(!(M.rhead = (OLink* )malloc((M.mu+1)*sizeof(OLink))))
	{
		exit(OVERFLOW);
	}
	if(!(M.chead = (OLink* )malloc((M.nu+1)*sizeof(OLink))))
	{
		exit(OVERFLOW);
	}
	M.rhead[] = NULL;
	M.chead[] = NULL;
	for(scanf(&i, &j, &e); i!=0; scanf(&i, &j, &e))
	{
		if(!(p = (OLink)malloc(sizeof(OLNode))))
		{
			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 );
			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;
		}
	}
	return OK;
}

此算法的时间复杂度为 O( t * max{ m, n } )
每建立一个非零元的结点时都要查询它在行表和列表的插入位置

STATUS AddCrossList(CrossList &A, CrossList B)
{
	//初始化两个辅助量
	pre = NULL;
	for(int j=1; j<=A.nu; j++)
	{
		hl[j]=A.chead[j];
	}
	for(row=1; row<A.mu; row++)
	{
		pa = A.rhead[row];
		pb = B.rhead[row];
		
		while(pb)
		{
			if(pa == NULL || pa->j > pb->j)
			{
				// 只要pb非空,必然要将pb结点加到
   				// pa中,并将pb结点从它的行链表中
   				// 删除,只删行链表为了判断本行加
   				// 操作是否结束.
				p = pb;
				pb = pb->right;
				//这个if处理行链表的链接改动
				if(pre == NULL)
				{
					A.rhead[row] = p;
				}
				else
				{
					// pre哪来的?
					// 注意后面对pre的处理
					pre->right = p;
				}

				p->right = pa;
				pre = p;
				
				// 这个if处理列链表的改动
				if(!A.chead[p->j] || \
				    A.chead[p->j]->i > p->i)
				{
					p->down = A.chead[p->j];
					A.chead[p->j] = p;
				}
				else
				{
					while(hl[p->j]->down && \
						hl[p->j]->i < p->i)
					{
						hl[p->j] = hl[p->j]->down;
					}
					p->down = hl[p->j]->down;
					hl[p->j]->down = p;
				}
				hl[p->j] = p;
			}
			else if(pa != NULL && pa->j < pb->j)
			{
				pre = pa;
				pa = pa->right;
			}
			else if(pa->j == pb->j)
			{
				p = pb;
				pb = pb->right;
				pa->e += p->e;
				if(pa->e == 0)
				{
					//删去这个结点
					//这个if从行链表删除该节点	
					if(pre == NULL)
					{
						A.rhead[pa->i] = pa->right;
					}
					else
					{
						pre->right = pa->right;
					}
					//从列链表删除该节点
					while(hl[p->j]->down != pa)
					{
						hl[p->j] = hl[p->j]->down;
					}
					hl[p->j]->down = pa->down;
					free(pa);
				}
			}		
		}
	}
	return OK;
}

标签:down,right,矩阵,pb,链表,零元,pa,十字
来源: https://blog.csdn.net/engineer0/article/details/111351558