在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code)
两位元格雷码:00 01 11 10
对应十进制 : 0 1 3 2
三位元格雷码:000 001 011 010 110 111 101 100
对应十进制 : 0 1 3 2 6 7 5 4
四位元的格雷码就是: 0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000
对应十进制 : 0 1 3 2 6 7 5 4 12 13 15 14 10 11 9 8
特别注意的是,生成的第一个和最后一个格雷码也是满足条件的----只有一位二进制数不同。
当然,格雷码并不一定非要以0开始,可以从任意处开始,依次往后,到末尾时下一个数就是从上面的标准格雷码起始处再往后,知道任意处的前一个位置,例如两位格雷码标准的 顺序是[0,1,3,2],当然也可以从元素为3的地方开始,那就是3,2,此时后面没有数了,就从标准格雷码起始处再继续,就是0,1,所以从元素3开始的地方的格雷码为[3,2,0,1]。
n位生成的格雷码数总的个数为2^n个,且这些格雷码数恰好是十进制取值0~2^n - 1,不重不漏。
生成n位标准顺序的格雷码代码如下:
for(int i=0;i<1<<n;i++)
graycode[i]=i^(i>>1);
采用异或的办法可以获得n位标准顺序的格雷码。
证明考虑两个方面:
1.这样生成的任意两个相邻的数字是满足格雷码的定义的,也就是graycode[i]^graycode[i+1]=2^p,
对于graycode[i]所对应的二进制,从右往左第p个位置首次出现0,容易证明:
graycode[i]^graycode[i+1]=i^(i/2)^(i+1)^((i+1)/2)=(i^(i+1))^((i/2)^((i+1)/2))=2^p;
2.这种取法可以不重不漏的取完0~2^n - 1
使用归纳法,n=2,3,4都是成立的,
假设n=k成立,那么n=k+1时候,由假设变量 i 从0~2^k - 1成立,那么只需要考虑 i 从 2^k~2^(k+1) -1 顺序取值,生成的格雷码也是在区间2^k~2^(k+1) -1内的,这里采用穷举法即可证明。