最近算法课上,老师布置了一个题目:
“格雷码”(Gray code)是一个长度为2n的序列,满足
A) 每个元素都是长度为n比特的串。
B) 序列中无相同元素。
C) 连续的两个元素恰好只有1比特的不同。例如,n=2时{00,01,11,10}
(1) 构造n=3时的“格雷码”。
(2) 利用分治策略设计一个算法对任意的n构造相应的“格雷码”
我是用了一个递归的方法来解决这个问题,下面是代码:
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**///////////////////////////////////////////
// 文件名:GrayCode.h
// 功 能:自动产生N位格雷码算法头文件
// 作 者:石头
// 创建日期:2006-03-05
// 修改日期:2006-03-05
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**///////////////////////////////////////////
#include <iostream>
#include <string>
#include <cstdio>
#include <string>
#include <stack>
#include <conio.h>
![](/Images/OutliningIndicators/None.gif)
using namespace std;
![](/Images/OutliningIndicators/None.gif)
//定义结点数据结构
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
typedef struct CodeNode
{
char *code; //格雷码串
struct CodeNode *next; //指向上一个码段的指针
}CodeNode, *CodeList;
![](/Images/OutliningIndicators/None.gif)
//函数声明
void GenerateGrayCode( int n );
CodeList CreateCodeList();
void IncreaseCode( CodeList L );
void PrintGrayCode( CodeList L );
void ReleaseGrayCode( CodeList L );
char *CodeCat( char *des, char *src );
![](/Images/OutliningIndicators/None.gif)
//定义全局变量
CodeList L;
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**///////////////////////////////////////////
// 文件名:GrayCode.cpp
// 功 能:自动产生N位格雷码算法实现文件
// 作 者:石头
// 创建日期:2006-03-05
// 修改日期:2006-03-05
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**///////////////////////////////////////////
#include "GrayCode.h"
![](/Images/OutliningIndicators/None.gif)
void main()
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
int nbits = 1;
char c;
while( nbits != 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
cout<<"Please input the bits of GrayCode(0:exit):";
cin>>nbits;
GenerateGrayCode( nbits ); //产生编码
cout<<"Done!"<<" Print Codes(y/n)?";
if( ((c = getch()) == 'y') || ((c = getch()) == 'Y') )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
printf("\n");
PrintGrayCode( L ); //打印编码
}
printf("\n");
}
ReleaseGrayCode( L ); //释放内存
}
![](/Images/OutliningIndicators/None.gif)
void GenerateGrayCode( int n ) //算法主体
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
if(n == 1)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
L = CreateCodeList();
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
GenerateGrayCode( n-1 );
IncreaseCode( L );
}
}
![](/Images/OutliningIndicators/None.gif)
CodeList CreateCodeList() //建立链表
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
CodeList Head = (CodeList)malloc(sizeof(CodeNode));
CodeList p = (CodeList)malloc(sizeof(CodeNode));
CodeList q = (CodeList)malloc(sizeof(CodeNode));
![](/Images/OutliningIndicators/InBlock.gif)
p->code = "0"; q->code = "1";
p->next = q; q->next = NULL;
![](/Images/OutliningIndicators/InBlock.gif)
Head->next = p;
![](/Images/OutliningIndicators/InBlock.gif)
return Head;
}
![](/Images/OutliningIndicators/None.gif)
void ReleaseGrayCode( CodeList L ) //释放内存空间
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
CodeList q;
while( L )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
q = L;
L = L->next;
free(q);
}
}
![](/Images/OutliningIndicators/None.gif)
void IncreaseCode( CodeList L) //做编码的一位扩展
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
CodeList p;
p = L;
int count = 0;
stack <char*> CodeStack; //定义栈
![](/Images/OutliningIndicators/InBlock.gif)
while( p->next )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
CodeStack.push( p->next->code );
p->next->code = CodeCat("0",p->next->code );
p = p->next;
count++;
}
![](/Images/OutliningIndicators/InBlock.gif)
while( count > 0 )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
CodeList q = (CodeList)malloc(sizeof(CodeNode));
q->code = CodeCat( "1",CodeStack.top() );
CodeStack.pop();
q->next = NULL;
p->next = q;
p = p->next;
count--;
}
}
![](/Images/OutliningIndicators/None.gif)
void PrintGrayCode( CodeList L ) //打印编码
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
CodeList p;
p = L->next;
while(p)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
cout<<p->code<<endl;
p = p->next;
}
}
![](/Images/OutliningIndicators/None.gif)
char *CodeCat( char *des, char *src ) //粘合两个字符串
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
char *stone = (char*)malloc((strlen(src)+strlen(des))*sizeof(char));
strcpy(stone,des);
strcat(stone,src);
![](/Images/OutliningIndicators/InBlock.gif)
return stone;总的来说这个算法对数据结构的应用还是比较成功的,但是在性能方面还有改进的空间,当N达到100的时候就会比较慢,下次有时间要把这个算法重写一下,以得到更高的效率.