数据结构与算法(C)—矩阵

本文变量命名前缀:

  1. 全局变量:g_
  2. 数组:a
  3. 指针:p
  4. 结构体:st
  5. unsigned int:ui

本文代码可以到Github下载:https://github.com/liyuewu-github/DataStructure

一、打印矩阵

/* 打印矩阵 */
void MatrixPrint(int * apMatrix [ ], int m, int n)
{
	int iR,iC;

	for (iR = 0; iR < m; ++iR)
	{
		for (iC = 0; iC < n; ++iC)
		{
			printf("%d ",apMatrix[iR][iC]);
		}
		printf("\n ");
	}
}

二、转圈打印矩阵

/* 矩阵转圈打印 */
/* 输入:
   1  2  3  4  
   5  6   7  8
   9  10  11  12
  13  14  15  16
输出:  1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10*/
void Matrix_CirclePrint(int* apMatrix[], int iR, int iC)
{
	int iTopR, iTopC;   /*左上角坐标*/
	int iBotR, iBotC;   /*右下角坐标*/
	int i,j,m,n;
	
	iTopR = iTopC = 0;
	iBotR = iR -1;
	iBotC = iC - 1;
	
	while ((iTopR<=iBotR) && (iTopC<=iBotC))
	{
		/* 规律:打印一行则遍历列,打印一列则遍历行 */
		if (iTopR == iBotR)  /* 一行 */
		{
			for (i = iTopC; i <= iBotC; i++)
			{
				printf("%d ",apMatrix[iTopR][i]);
			}
		}
		else if (iTopC == iBotC)   /* 一列 */
		{
			for (i = iTopR; i <= iBotR; i++)
			{
				printf("%d ",apMatrix[i][iTopC]);
			}
		}
		else /* 多行多列 */
		{
			for (i = iTopC; i < iBotC; i++) /* 正向打印行,留最后一个元素,作为下列起始 */
			{
				printf("%d ",apMatrix[iTopR][i]);
			}
			for (j = iTopR; j < iBotR; j++) /* 正向打印列,留最后一个元素,作为下行起始 */
			{
				printf("%d ",apMatrix[j][iBotC]);
			}
			for (m = i; m > iTopC; m--) /* 逆向打印行,留最后一个元素,作为下列起始 */
			{
				printf("%d ",apMatrix[iBotR][m]);
			}
			for (n = j; n > iTopR; n--) /* 逆向打印列,一圈结束 */
			{
				printf("%d ",apMatrix[n][iTopC]);
			}
		}
		
		/* 下一圈 */
		iTopR++;
		iTopC++;
		iBotR--;
		iBotC--;		
	}
	printf("\n ");

}

三、方阵顺时针旋转90度

/* 正方形矩阵顺时针旋转90度 */
/* 
输入:
   1  2  3  4  
   5  6   7  8
   9  10  11  12
  13  14  15  16
输出:
   13  9   5  1
   14  10  6  2
   15  11  7  3
   16  12  8  4*/
 /* 由外到内依次旋转,一轮替换1->4;4->16;16->13;13->1; 轮数为行或列元素个数 */
int ** Matrix_Rorate(int * apMatrix [ ], int iR, int iC)
{
	int iTopR, iTopC;   /*左上角坐标*/
	int iBotR, iBotC;   /*右下角坐标*/
	int iTime;   /*旋转次数*/
	int iTmp;
	int **ppM;
	int i;
	ppM = malloc(iR * sizeof(int));
	for (i = 0; i < iR; ++i)
	{
		ppM[i] = apMatrix[i];
	}

	iTopR = iTopC = 0;
	iBotR = iR -1;
	iBotC = iC - 1;

	while (iTopR<iBotR)
	{
		iTime = iBotR - iTopR; /* 旋转次数即行或列的元素个数 */
		for (i = 0; i < iTime; ++i)
		{
			iTmp = apMatrix[iTopR][iTopC+i];
			apMatrix[iTopR][iTopC+i] = apMatrix[iBotR-i][iTopC]; /*13->1*/
			apMatrix[iBotR-i][iTopC] = apMatrix[iBotR][iBotC-i]; /*16->13*/
			apMatrix[iBotR][iBotC-i] = apMatrix[iTopR+i][iBotC]; /*4->16*/
			apMatrix[iTopR+i][iBotC] = iTmp; /*1->4*/
		}

		/* 下一圈 */
		iTopR++;
		iTopC++;
		iBotR--;
		iBotC--;		
	}

	return ppM;
}

四、“之”字形打印矩阵

/* “之”字形打印矩阵 */
/* 
输入:
   1  2  3  4  
   5  6   7  8
   9  10  11  12
  13  14  15  16
输出:1 2 5 9 6 3 4 7 10 13 14 11 8 12 15 16*/
void Matrix_SnakePrint(int* apMatrix[], int iR, int iC)
{
	int iTopR, iTopC;   /*左上角坐标*/
	int iBotR, iBotC;   /*右下角坐标*/
	int iRev;    /*折叠打印*/
	int i,j;

	iTopR = iTopC = 0;
	iBotR = iBotC = 0;
	iRev = 0;

	/* 规律:
	1、行列没到底,斜线首坐标(iTopR, iTopC++),尾坐标(iBotR++, iBotC)
	2、行到底,斜线尾坐标(iBotR, iBotC++)
	3、列到底,斜线首坐标(iTopR++, iTopC)*/
	while (iTopR <= iR)
	{
		if (iRev) /* 向下打印,行++,列-- */
		{
			for (i = iTopR,j=iTopC; i < iBotR+1; i++,j--)
			{
				printf("%d ",apMatrix[i][j]);
			}
		}
		else /* 向上打印,行--,列++ */
		{
			for (i = iBotR,j=iBotC; j < iTopC+1; i--,j++)
			{
				printf("%d ",apMatrix[i][j]);
			}
		}

		if (iTopC == iC-1) /* 打印到了最后一列,行号下移 */
		{
			iTopR++;
		}
		else /* 不到了最后一列,列号下移 */
		{
			iTopC++;
		}

		if (iBotR==iR-1) /* 打印到了最后一行,列号下移 */
		{
			iBotC++;
		}
		else /* 不到了最后一行,行号下移 */
		{
			iBotR++;
		}
		
		iRev = !iRev;
	}
	printf("\n ");
	return;
}

五、测试程序

int main()
{
	int aM[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
	int *pM[4] = {aM[0],aM[1],aM[2],aM[3]};
	int **ppM;

	printf("--Circle Print--\n");
	Matrix_CirclePrint(pM, 4, 4);

	printf("--Snake Print--\n");
	Matrix_SnakePrint(pM, 4, 4);

	printf("--Rorate Print--\n");
	printf("input:\n ");
	MatrixPrint(pM, 4, 4);

	ppM = Matrix_Rorate(pM, 4, 4);

	printf("output:\n ");
	MatrixPrint(pM, 4, 4);



	return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值