lwq的学习日记(6)

矩阵的压缩与转置,以及快速转置

1:矩阵的存储

typedef struct syz {
	
	int rows, cols;
	int value;
}T;

分别代表矩阵的行,列和值

2:矩阵的压缩

typedef struct {
	T  v[N+1];
	int mu, nu, tu;
}Tsyz;

用三元组进行表示,分别代表行,列,及有效点的个数

3:创建一个矩阵

void c_jz(Tsyz &M)
{
	int flag = 0;
    //flag的作用是检查输入点是否超出三元组的承载
	while (!flag)
	{
		int co, ro, n;
		cin >> co >> ro >> n;
		M.mu = co, M.nu = ro, M.tu = n;
		if (co * ro < n)
		{
			cout << "超出矩阵最大承载请重新输入" << endl;

		}
		else
		{
			cout << "请按照顺序输入矩阵的每个元素" << endl;
			flag = n;
		}
	}
	int t1 = 0, t2 = 0;
    //t1,t2用来保证按照递增顺序插入
	for (int i = 1; i <= flag; i++)
	{
		int a, b, c;
		
		cin >> a >> b >>c;
        //ggboy数组来确保三元组的元素不会重复出现
		if (ggboy[a][b])
		{
			cout << "输入错误,输入的下标重复,请重新输入!" << endl;
			i = i - 1;
		}
		else if ((a == t1 && b > t2) || (a < t1))
		{
            //确保按照下标递增顺序输入数据。
			cout << "输入错误,下标输入时要递增输入,请重新输入!" << endl;
			i = i - 1;
		}
		else
		{
            //若符合条件直接插入即可
			M.v[i] = { a,b,c };
			ggboy[a][b] = 1;
			t1 = a, t2 = b;
		}
		

	}

}

4:矩阵的输出

void sc(Tsyz& M)
{
	int n = 0;
	n = M.mu * M.nu;
    //n表示矩阵所有点的个数
	memset(cnt, 0, sizeof cnt);
    //memset函数的作用是将数组全部初始化一个值,需要特别注意的是,对于二维数组一般只能初始化未0
	for (int i = 1; i <= M.tu; i++)
	{
        //cnt用来标记矩阵中各个点的位置
		cnt[M.v[i].rows][M.v[i].cols] = M.v[i].value;
	}
	for (int i = 1; i <= M.mu; i++)
	{
		for (int j = 1; j <= M.nu; j++)
		{
			if (cnt[i][j])
			{
                //若已被标记,直接输入值即可
				cout << cnt[i][j] << ' ';
			}
			else
			{
                 //若未被标记,则说明该值为0
				cout << 0 << ' ';
			}
		}
		cout << endl;
	}
}

5:矩阵的转置

void ptzz(Tsyz &M, Tsyz& Q)
{
	Q.mu = M.mu;
	Q.nu = M.nu;
	Q.tu = M.tu;
	//非空
	if (Q.tu)
	{
		int q = 1;
		
		for (int i = 1; i <= M.nu; i++)//列
		{
            //按列对矩阵进行转置,将原来的行按顺序转化为列
			for (int j = 1; j <= M.tu;j++)
			{
				if (M.v[j].cols == i)
				{
					Q.v[q].cols = M.v[j].rows;
					Q.v[q].rows = M.v[j].cols;
					Q.v[q].value = M.v[j].value;
					q++;

				}
			}
		}


	}
	sc(Q);

}

普通转置的时间复杂度为o(n^2);

6:矩阵的快速转置

void q_zz(Tsyz M, Tsyz& Q)
{
	
	Q.mu = M.nu, Q.nu = M.mu, Q.tu = M.tu;
	if (Q.tu)
	{
		for (int i = 1; i <= M.nu; i++) sum[i] = 0;
		for (int j = 1; j <= M.tu; j++) sum[M.v[j].cols]++;//记录每一列中元素的个数
		cp[1] = 1;
		for (int i = 2; i <= M.nu; i++)
		{
			cp[i] = cp[i - 1] + sum[i - 1];
            //每列中首个非零元的位置
            
		}
		for (int j = 1; j <= M.tu; j++)
		{
			int i = M.v[j].cols;
			int q = cp[i];
			Q.v[q].cols = M.v[j].rows;
			Q.v[q].rows = M.v[j].cols;
			Q.v[q].value = M.v[j].value;
			cp[i]++;

		}
	}
	sc(Q);
	

}

时间复杂度为O(n);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值