在一组树的编码中,若任意两个相邻的代码只有一位二进制不同,则称这种编码为格雷码(GrayCode)。
请编写一个函数,使用递归的方法生成N位的格雷码并且保证这个函数的健壮性。
看到题目开始确实没有思路,不妨我们先画一下格雷码树结构。3位格雷码。
0 1
0 1 1 0
0 1 1 0 0 1 1 0
我们可以发现这样的规律,最高节点0和1对应的子树是对称的。
也就是说
f(n+1) = ‘0’ + f(n) (最高位为0时第n位格雷码)
f(n+1) = '1' + f '(n) (最高位为1时 f'(n)对应第n位格雷码的对称解)
规律发现了,但是用递归求解的对称感觉不容易下手。
我们要找出更容易完成递归的规律。
观察树,当前面m个点1的个数为奇数时,我们后一个解,我们加上左子树1,右子树0。如果是偶数,加上左子树0,右子树1。
按照这个规律写出代码。
#include<iostream>
#include <vector>
using namespace std;
void GrayCode(int n,vector<int>temp,vector<vector<int>>&ret,int numof1)
{
if(n == 0) //终止条件
{
ret.push_back(temp);
return;
}
if(numof1%2==0) //偶数个1
{
temp.push_back(0);//先放0
GrayCode(n-1,temp,ret,numof1);
temp.pop_back();//注意pop出0节点
temp.push_back(1);
GrayCode(n-1,temp,ret,numof1+1);//1的个数加1
}
else if(numof1%2==1) //奇数个1
{
temp.push_back(1);//先放1
GrayCode(n-1,temp,ret,numof1+1);
temp.pop_back();
temp.push_back(0);//后放0
GrayCode(n-1,temp,ret,numof1);
}
}测试代码
int main(){
vector<int> temp;//中间量
vector<vector<int> > ret;//解
int n = 8; //n位格雷码
GrayCode(n,temp,ret,0);
for(int i=0;i<ret.size();++i)
{
cout<<endl;
for(int j=0;j<ret[0].size();++j)
{
cout<<ret[i][j];
}
}
}
本文介绍了一种递归生成N位格雷码的方法,并详细解释了其背后的数学原理及编码规律。通过观察格雷码树结构,文章揭示了生成更高位数格雷码的递归模式,并给出了具体的C++实现代码。
2208

被折叠的 条评论
为什么被折叠?



