利用一维数组表示一个可扩展的n*n矩阵的一种方法

1.设计背景

        之所以想了这样一个方法,是因为在写程序的时候遇到了相应的问题,为了解决而想出来的。当时需要构造并使用一个图结构来实现一些功能,我选择了用邻接矩阵和顶点列表的形式来表示一个图,而我又选择了使用一维数组来表示一个邻接矩阵。但是这里出现了问题,我们的图的顶点个数可以增加,也就是说邻接矩阵会不断增大,如果使用传统的方法用数组第n*i+j项表示矩阵中(i,j)位置的元素,当矩阵由N*N变为(N+1)*(N+1)时,这种对应关系就会被破坏。比如本来一个数组a表示3*3矩阵,那a[6]表示的是(2,0)的元素,但矩阵扩展为4*4后,a[6]变为(1,2)的元素而不是对应原来位置的(2,0)的元素,这就会带来错误。

当然,我们可以用邻接表或其他各种方式来表示图来轻松的避免这个问题,我们也可以直接建立二维数组表示邻接矩阵,但我在思考之后想了一个办法来解决上述问题,从而仍然使用一个一维数组来表示一个可以变大的n*n矩阵,也就是一个可增加顶点的图的邻接矩阵,也许某种情况下这会有一定作用,所以在此进行一下分享(当然这并不难想,可能大家都想得出来,我只是分享一下我的想法。。。)

2.实现方法

我的思路就是不再使用上述传统的方法,也就是数组第n*i+j项表示矩阵中(i,j)位置的元素,而是改变一维数组中一项数据与矩阵中一项数据的对应关系,从而实现目的,我们可以这样形象的来想,从1*1的矩阵开始,它只有一个元素,之后每次扩展都是在原来的左边的下边加一圈,那么每次扩展时,我们新增的元素按照从新添的最左的一列向下到最下一行,在向右的方法逐一填充。

这样的意义是,每次由 N*N矩阵扩展为(N+1)*(N+1)时新增提案的2N+1个元素都被排在了新增添的格子中,没有和原来的冲突。需要注意的是,我这里的填写,指的是填写对应一维数组的元素的索引值,我们应当从N*N开始,将其填到(0,N+1)这个格子,然后将这个数+1填到下面的格子,按上面箭头的顺序一直到(N+1)*(N+1)-1填到(N+1,0)这个格子结束,这就是我的基本思路,这里说的不够清晰,我会在具体描述一下。

                                 图中的数字就是对应一维数组的索引值

要记住,矩阵的虚拟的,抽象的,我们并没有实际的矩阵,我们只有一个一维数组,所谓的矩阵是由一维数组中的元素通过一一对应的方式在你的脑海中填充到特定的位置而形成的,上面这种对应方式无疑是一个一一对映,因为按这种方法构造,从0开始的N*N个数被不重复的填入了矩阵,而填入方法就是上面说过的,从1*1开始,每扩展一次,就从上至下,再从右至左写。

        这种从实际存储的一维数组到虚拟的二维矩阵的关系是可以数学表示的,因为我们的需求都是给定了矩阵中的某个元素,所以这里给出的就是(i,j)元素怎样在一维数组中寻找其索引k:

        若 i <= j    则  k = j * j + i

        若 i > j    则  k = i * i + 2* i - j

        这是根据规律总结出来的,具体数学原理就不说了。

3.总结

        总之这是一种可行的用一维数组来表示可扩展的N*N矩阵的方法,但这种方法我目前还没想到怎么实现边长的减小,也就是说如果用这种方法表示图的邻接矩阵,图的顶点没法删除,这个问题目前我还没想到怎样解决,较为可惜。这并不是什么困难的方法,只是我自己想到后分享一下,希望对别人有所帮助。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值