C++实现矩阵原地转置算法
2023-06-13 09:15:42 时间
本文实例描述了C++实现矩阵原地转置算法,是一个非常经典的算法,相信对于学习C++算法的朋友有很大的帮助。具体如下:
一、问题描述
微软面试题:将一个MxN的矩阵存储在一个一维数组中,编程实现矩阵的转置。
要求:空间复杂度为O(1)
二、思路分析
下面以一个4x2的矩阵A={1,2,3,4,5,6,7,8}进行分析,转置过程如下图:
图中右下角的红色数字表示在一维数组中的下标。矩阵的转置其实就是数组中元素的移动,具体的移动过程如下图:
我们发现,这些移动的元素的下标是一个个环,下标1的元素移动到4,下标4的元素移动到2,下标2的元素移动到1。在编写程序的时候,我们需要解决两个问题:第一个是如何判定环是否重复(已处理过);第二个是如何计算当前元素下标的前驱与后继。
第一个问题:如何判断环是重复已处理过的?因为我们遍历整个数组时下标是从小到大的,所以如果是第一次遍历该环,则第一个下标肯定是这个环中最小的。如果一个环被处理过,那么总能找到一个它的后继是小于它的。从上图可以明显看出来。
第二个问题:如何计算当前元素下标的前驱与后继?假设转置前某个元素的数组下标为i,则它所在行列为(i/N,i%N),转置后所在行列则为(i%N,i/N),可计算转置后数组下标为(i%N)*M+i/N,此为i的后继。假设转置后某个元素的数组下标为i,则它所在行列为(i/M,i%M),则转置前所在行列为(i%M,i/M),可计算此时下标为(i%M)*N+i/M,此为i的前驱。
三、代码实现如下:
/************************************************************************* >FileName:matrix_transpose.cpp >Author:SongLee ************************************************************************/ #include<iostream> usingnamespacestd; /*后继*/ intgetNext(inti,intm,intn) { return(i%n)*m+i/n; } /*前驱*/ intgetPre(inti,intm,intn) { return(i%m)*n+i/m; } /*处理以下标i为起点的环*/ voidmovedata(int*mtx,inti,intm,intn) { inttemp=mtx[i];//暂存 intcur=i;//当前下标 intpre=getPre(cur,m,n); while(pre!=i) { mtx[cur]=mtx[pre]; cur=pre; pre=getPre(cur,m,n); } mtx[cur]=temp; } /*转置,即循环处理所有环*/ voidtranspose(int*mtx,intm,intn) { for(inti=0;i<m*n;++i) { intnext=getNext(i,m,n); while(next>i)//若存在后继小于i说明重复 next=getNext(next,m,n); if(next==i)//处理当前环 movedata(mtx,i,m,n); } } /*输出矩阵*/ voidprint(int*mtx,intm,intn) { for(inti=0;i<m*n;++i) { if((i+1)%n==0) cout<<mtx[i]<<"\n"; else cout<<mtx[i]<<""; } } /*测试*/ intmain() { intmatrix[4*2]={1,2,3,4,5,6,7,8}; cout<<"Beforematrixtransposition:"<<endl; print(matrix,4,2); transpose(matrix,4,2); cout<<"Aftermatrixtransposition:"<<endl; print(matrix,2,4); return0; }
运行结果如下图所示:
相关文章
- 老梁聊C++,为什么不能修改set里的值?如果非要修改怎么办?
- 大数运算的算法设计和C++实现[通俗易懂]
- 快速排序算法——C/C++
- 简单易懂的Dinic算法C++实现 含算法解释
- c++ auto类型_auto C++
- C/C++ 数据结构与算法笔记
- C++继承和派生是什么意思(通俗易懂)
- C++ set(STL set)容器是什么
- C++ is_sorted(STL is_sorted)排序算法详解
- C++ upper_bound(STL upper_bound)二分查找算法详解
- C++ 随机数生成器和随机数引擎及其两者间关系解析
- 用C++实现DBSCAN聚类算法
- 海量数据处理系列之:用C++实现Bitmap算法
- C++泛型算法的一些总结
- C++类静态成员与类静态成员函数详解
- 关于C++静态成员函数访问非静态成员变量的问题
- 利用C++的基本算法实现十个数排序
- k均值算法c++语言实现代码
- C++实现汉诺塔算法经典实例