最通俗易懂的魔方阵C语言实现

该代码仅实现了任意奇数n阶矩阵的魔方阵。
每一行、每一列、对角线之和都相等。
例如3阶魔方阵如下:
     8  1  6 
     3  5  7
     4  9  2
算法:1,先给备用数组内所有数赋初值0;(下面的i代表行号,j代表列号)(第1步是为第7步做铺垫)
          2,第0行的中间那个数a[i][j]=0,此时i = 0,j = n/2;
  3,当前的数在首行(i=0)时,下一个数放在最后一行(i=n-1),j++;
  4,当前的数在最后一列(j=n-1)时,下一个数放在第一列(j=0),i--;
  5,如果同时满足了(i=0和j=n-1),那么进行i=n-1,j=0;
  6,如果3.4.5都不满足,就进行i--,j++;
  7,经过上面3步的判断,找到了新的i和j的值,如果此时a[i][j]放的值是0,代表这地方未被用过,可放下一个数;
    如果此时这里放的不是0,代表已经被用过了,那么下一个数就直接放到这个数的前面那个数的的下面

   (比如本例n=3时:4本该放到a[0][1]的,但a[0][1]被1占了,所以,就直接把4放到4的前面那个数3的下面咯。)

备注:1,代码可以说很通俗易懂了,但也很长很多,所以大家可以自由简化;
      2,本例中因为把备用数组弄的10*10的,所以只能输入10内的奇数,大家可以把数组设成100*100甚至更大,从而可以输入100内甚至更大的奇数了。
  3,偶数阶魔方存在,大家可以百度搜别人的博客看哈。
#include<stdio.h>
void main()
{
	int a[10][10];
	int i,j,ok,n,m;

	for(i = 0;i < 10;i++)                   /*给备用的数组做初始化*/
	{
		for(j = 0;j < 10;j++)
			a[i][j] = 0;
	}

	ok = 0;                                  /*限定输入的数必须满足要求*/
	while(ok == 0)
	{
		printf("Please input a number as the value of n:(必须是10以内的奇数)\n");
	    scanf("%d",&n);
		if(n % 2 != 0 && n > 0 && n < 10 )
			ok = 1;
		else
			ok = 0;
	}

	i = 0;
	j = n/2;
	a[i][j] = 1;
	for(m = 2;m <= n*n;m++)                  /*因为1已经放好了,所以我们从2开始放*/
	{

		if((i == 0) && (j != n-1))            /*算法中的第3步*/
		{
			i = n-1;
			j = j+1; 
			if(a[i][j] == 0)                  /*算法中的第7步*/
				a[i][j] = m;
			else
			{
				i = 1;
				j = j - 1;
				a[i][j] = m;
			}
		}

		else if((i != 0) && (j == n-1))      /*算法中的第4步*/
		{
			i = i-1;
			j = 0;
			if(a[i][j] == 0)                /*算法中的第7步*/
				a[i][j] = m;
			else
			{
				i = i + 1;
				j = n - 1;
				a[i][j] = m;
			}
		}

	   else if((i == 0) && (j == n-1))       /*算法中的第5步*/
		{
			i = n-1;
			j = 0;
			if(a[i][j] == 0)                 /*算法中的第7步*/
				a[i][j] = m;
			else
			{
				i = 1;
				j = n - 1;
				a[i][j] = m;
			}
		}

		else                                 /*算法中的第6步*/
		{
			i = i-1;
			j = j+1;
			if(a[i][j] == 0)                 /*算法中的第7步*/
				a[i][j] = m;
			else
			{
				i = i + 2;
				j = j - 1;
				a[i][j] = m;
			}
		}
	}

    printf("%d阶魔方阵:\n",n);
	for(i = 0;i < n;i++)                        /*输出数组*/
	{
		for(j = 0;j < n;j++)
		{
			printf("%4d",a[i][j]);
		}
		printf("\n");
	}
}


  • 62
    点赞
  • 154
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
哈夫曼树是一种特殊的二叉树,用于压缩数据。它的特点是,将频率较高的字符用较短的编码表示,而将频率较低的字符用较长的编码表示,以达到压缩数据的目的。 哈夫曼树的构建过程如下: 1. 将所有字符及其频率按照频率从小到大的顺序排列,构成一个森林,每个节点都是一棵只包含一个字符的树。 2. 从森林中选出两棵根节点权值最小的树,将它们合并成一棵新的树,新树的根节点的权值为两棵子树的权值之和。 3. 将新树插入到森林中,重复步骤2,直至森林中只剩下一棵树,即哈夫曼树。 下面是用C语言实现哈夫曼树的代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_TREE_SIZE 1000 typedef struct { int weight; // 权值 int parent; // 父节点在数组中的下标 int lchild, rchild; // 左右孩子在数组中的下标 } HTNode, *HuffmanTree; typedef char **HuffmanCode; // 编码表 // 选择两个权值最小的节点 void select(HuffmanTree tree, int n, int *s1, int *s2) { int min1 = 0, min2 = 0; for (int i = 1; i <= n; i++) { if (tree[i].parent == 0) { if (tree[i].weight < tree[min1].weight) { min2 = min1; min1 = i; } else if (tree[i].weight < tree[min2].weight) { min2 = i; } } } *s1 = min1; *s2 = min2; } // 构建哈夫曼树 void createHuffmanTree(HuffmanTree *tree, int *w, int n) { if (n <= 1) return; int m = 2 * n - 1; *tree = (HuffmanTree) malloc((m + 1) * sizeof(HTNode)); // 初始化前n个节点 for (int i = 1; i <= n; i++) { (*tree)[i].weight = w[i]; (*tree)[i].parent = 0; (*tree)[i].lchild = 0; (*tree)[i].rchild = 0; } // 构建哈夫曼树 for (int i = n + 1; i <= m; i++) { int s1, s2; select(*tree, i - 1, &s1, &s2); (*tree)[s1].parent = i; (*tree)[s2].parent = i; (*tree)[i].lchild = s1; (*tree)[i].rchild = s2; (*tree)[i].weight = (*tree)[s1].weight + (*tree)[s2].weight; } } // 生成哈夫曼编码 void createHuffmanCode(HuffmanTree tree, HuffmanCode *code, int n) { *code = (HuffmanCode) malloc((n + 1) * sizeof(char *)); char *temp = (char *) malloc(n * sizeof(char)); // 临时存储编码 for (int i = 1; i <= n; i++) { int start = n - 1; int j = i; int parent = tree[i].parent; while (parent != 0) { if (tree[parent].lchild == j) { temp[start] = '0'; } else { temp[start] = '1'; } start--; j = parent; parent = tree[j].parent; } (*code)[i] = (char *) malloc((n - start) * sizeof(char)); strcpy((*code)[i], &temp[start + 1]); } free(temp); } int main() { int n; scanf("%d", &n); int *w = (int *) malloc((n + 1) * sizeof(int)); for (int i = 1; i <= n; i++) { scanf("%d", &w[i]); } HuffmanTree tree; createHuffmanTree(&tree, w, n); HuffmanCode code; createHuffmanCode(tree, &code, n); // 输出每个字符的编码 for (int i = 1; i <= n; i++) { printf("%d: %s\n", i, code[i]); } return 0; } ``` 在这个代码中,我们定义了 `HTNode` 结构体来表示哈夫曼树的节点,用 `HuffmanTree` 来表示整棵树,用 `HuffmanCode` 来表示编码表。我们使用了 `select` 函数来选择两个权值最小的节点,使用 `createHuffmanTree` 函数来构建哈夫曼树,使用 `createHuffmanCode` 函数来生成编码表,最后输出每个字符的编码。 需要注意的是,这个代码中只考虑了字符的权值,实际应用中还需要考虑字符的出现次数。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值