这是15年前,环球科学杂志上的一篇文章,作者写了一个类似简单魔方的小游戏:M12

这是游戏说明:

给大家翻译一下:
游戏由两个按键控制,一个是“INVERT“,另一个是“MERGE”。“INVERT”英文的意思是“反向“,能将“1,2,3,4,…,12“,排列成“12,11,10…,1”,而“MERGE”英文的意思是“混合”,能将“1,2,3,4,…,12“,排列成“1,12,2,11,3,10,4,9,5,8,6,7”,如图:


游戏开始时按下“RANDOMIZE”(随机)键,将数字打乱,让玩家通过这两个键还原,这是不是类似魔方的玩法,“CUSTOM”键可以将一组“IMIM…“的按键方式记下来,自定义这样的组合。

游戏并不是没有规律,当"INVERT"按两次就回归原始状态了,这里就不做演示了。””"MERGE"则是按下11次就回归原始状态,如下图:









这时再按一次“MERGE”,就恢复了最初的状态。

因此整个过程能用一个二叉树表示:

我们用的是广度优先算法,从顺序上看是这样的:

这里面不排除有重复值,这个可以在软件中筛选掉。

游戏提示中写道,这将有12×11×10×9×8种(95040种)组合,软件在遍历过程中实际用时8小时,因为我每做多线程,操作太麻烦,因此我我的思路是这样的,我从不打乱的状态去遍历,排除掉重复的,将遍历得到的结果和路径全部记下,这样我打乱之后直接在记录中查找,找到还原的最短路径,再按记下的路径还原,这样只需要跑一次8小时,永久不耗时,记录也只用了9kB的硬盘空间。

#include <stdio.h>
#include <malloc.h>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define MaxSize 2000000//如果没有运行完就退出,修改这里
#define GuangduZize 800//M12,1000000;M6,800
#define ShuzuSize 1000//M12,1000000;M6,1000
typedef char ElemType;
typedef struct node{long data;      //数据元素int shuzu[12];struct node *lchild, *rchild;    //指向左孩子右孩子
}BTNode, *Bitree;BTNode *que[30000];
FILE* fp;
int record[ShuzuSize][12];
int flag;//find "  1  2  3  4  5  6  7  8  9 10 11 12"
int sameflag;
long front = 0, rear = 0;
void DispPath4(BTNode *b,int ch);/*******************queue*******************/
typedef struct _q_node
{BTNode *t_node;struct _q_node *next;
}QNode;typedef struct _Queue
{QNode *head;QNode *tail;
}Queue;Queue* init_queue()
{Queue *queue=(Queue*)malloc(sizeof(Queue));queue->head = queue->tail = NULL;return queue;
}int enQueue(Queue *pQueue,BTNode *pTNode)
{QNode *pQNode = (QNode *)malloc(sizeof(QNode));pQNode->t_node = pTNode;if(pQueue->head == NULL){//when it's emptypQueue->head = pQNode; pQueue->tail = pQNode;     }    else{pQueue->tail->next = pQNode;pQueue->tail = pQNode;}return 0;
}QNode* deQueue(Queue *pQueue)
{if(pQueue->head == NULL){return NULL;}QNode *deNode= pQueue->head;pQueue->head = pQueue->head->next;  return deNode;
}BTNode* init_TNode(int data)
{BTNode  *new_node = (BTNode*)malloc(sizeof(BTNode));new_node->data=data;new_node->lchild = new_node->rchild = NULL;return new_node;
}//0:empty
int ifEmpty(Queue *pQueue)
{if(pQueue->head == NULL){//printf("empty tree\n");return 0;}//printf("queue is not empty\n");return 1;
}
/****************************************************/
int merge(int* input, int* output)
{output[0]=input[0];output[1]=input[11];output[2]=input[1];output[3]=input[10];output[4]=input[2];output[5]=input[9];output[6]=input[3];output[7]=input[8];output[8]=input[4];output[9]=input[7];output[10]=input[5];output[11]=input[6];return 1;
}
int invert(int* input, int* output)
{int temp,k=0;merge(input, output);while(k<6)//12/2{temp=input[k];output[k]=input[11-k];//12-k-1output[11-k]=temp;//12-k-1k++;}return 1;
}int merge6(int* input, int* output)
{output[0]=input[0];output[1]=input[5];output[2]=input[1];output[3]=input[4];output[4]=input[2];output[5]=input[3];return 1;
}
int invert6(int* input, int* output)
{int temp,k=0;merge6(input, output);while(k<3)//6/2{temp=input[k];output[k]=input[5-k];//12-k-1output[5-k]=temp;//12-k-1k++;}return 1;
}int findFlag(int n[]){if(flag==0 | (n[0]==1 && n[1]==2 && n[2]==3 && n[3]==4 && n[4]==5)){return 0;}else{return 1;}
}int findSameFlag4(int n[]){long i;for(i=0;i<ShuzuSize;i++){//fprintf(fp,"%3d\t%2d%2d%2d%2d%2d%2d%2d%2d%2d%2d%2d%2d\n",i,n[0],n[1],n[2],n[3],n[4],n[5],record[i][0],record[i][1],record[i][2],record[i][3],record[i][4],record[i][5]);if(n[0]==record[i][0] && n[1]==record[i][1] && n[2]==record[i][2] && n[3]==record[i][3] && n[4]==record[i][4]){return 0;}}return 1;
}BTNode* CreateBiTree(int n[12])//m6,层序创建二叉树
{static BTNode *t, *bt, *q;long x=1;int i,j;//1bt = (BTNode*)malloc(sizeof(BTNode));bt->data = 0;for(i=0;i<6;i++){bt->shuzu[i]=n[i];}for(j=0;j<6;j++){//将数组写入已打印队列,以便查找有无重复record[0][j]=n[j];}bt->rchild = bt->lchild = NULL;que[rear++] = bt;while(x<GuangduZize & front<rear){t = que[front];front++;//M,leftif(flag){merge6(t->shuzu,n);q = (BTNode*)malloc(sizeof(BTNode));q->data = x;for(i=0;i<6;i++){q->shuzu[i]=n[i];}flag=findFlag(n);if(!findSameFlag4(n)){x+=2;//v3.2版本修复bugcontinue;}else{for(i=1;i<ShuzuSize;i++){if(record[i][0]==0){for(j=0;j<6;j++){record[i][j]=n[j];}break;}}}t->lchild = q;q->rchild = q->lchild = NULL;que[rear++] = q;}else{t->lchild = NULL;printf("找到序号为:%d\n",x-1);break;}if(flag){invert6(t->shuzu,n);q = (BTNode*)malloc(sizeof(BTNode));q->data = x+1;for(i=0;i<6;i++){q->shuzu[i]=n[i];}flag=findFlag(n);if(!findSameFlag4(n)){x+=2;//v3.2版本修复bugcontinue;}else{for(i=1;i<ShuzuSize;i++){if(record[i][0]==0){for(j=0;j<6;j++){record[i][j]=n[j];}break;}}}t->rchild = q;q->rchild = q->lchild = NULL;que[rear++] = q;}else{t->rchild = NULL;printf("找到序号为:%d\n",x);break;}x+=2;}return bt;
}BTNode* CreateBiTree2(int n[12])//m6,由1~6演变输出到文件,层序创建二叉树
{static BTNode *t, *bt, *q;long x=1;int i,j;//1bt = (BTNode*)malloc(sizeof(BTNode));bt->data = 0;for(i=0;i<6;i++){bt->shuzu[i]=n[i];}for(j=0;j<6;j++){//将数组写入已打印队列,以便查找有无重复record[0][j]=n[j];}bt->rchild = bt->lchild = NULL;que[rear++] = bt;while(x<GuangduZize & front<rear){t = que[front];front++;//M,leftif(flag){merge6(t->shuzu,n);q = (BTNode*)malloc(sizeof(BTNode));q->data = x;for(i=0;i<6;i++){q->shuzu[i]=n[i];}//flag=findFlag(n);if(!findSameFlag4(n)){x+=2;//v3.2版本修复bugcontinue;}else{for(i=1;i<ShuzuSize;i++){if(record[i][0]==0){for(j=0;j<6;j++){record[i][j]=n[j];}break;}}}t->lchild = q;q->rchild = q->lchild = NULL;que[rear++] = q;}else{t->lchild = NULL;printf("找到序号为:%d\n",x-1);break;}if(flag){invert6(t->shuzu,n);q = (BTNode*)malloc(sizeof(BTNode));q->data = x+1;for(i=0;i<6;i++){q->shuzu[i]=n[i];}//flag=findFlag(n);if(!findSameFlag4(n)){x+=2;//v3.2版本修复bugcontinue;}else{for(i=1;i<ShuzuSize;i++){if(record[i][0]==0){for(j=0;j<6;j++){record[i][j]=n[j];}break;}}}t->rchild = q;q->rchild = q->lchild = NULL;que[rear++] = q;}else{t->rchild = NULL;printf("找到序号为:%d\n",x);break;}x+=2;}return bt;
}BTNode* CreateBiTree5(int n[12])//m6,由1~6演变输出到文件,层序创建二叉树
{static BTNode *t, *bt, *q;long x=1;int i,j;//1bt = (BTNode*)malloc(sizeof(BTNode));bt->data = 0;for(i=0;i<6;i++){bt->shuzu[i]=i+1;}for(j=0;j<6;j++){//将数组写入已打印队列,以便查找有无重复record[0][j]=j+1;}bt->rchild = bt->lchild = NULL;que[rear++] = bt;while(x<GuangduZize & front<rear){t = que[front];front++;if(flag){invert6(t->shuzu,n);q = (BTNode*)malloc(sizeof(BTNode));q->data = x+1;for(i=0;i<6;i++){q->shuzu[i]=n[i];}//flag=findFlag(n);if(!findSameFlag4(n)){x+=2;//v3.2版本修复bugcontinue;}else{for(i=1;i<ShuzuSize;i++){if(record[i][0]==0){for(j=0;j<6;j++){record[i][j]=n[j];}break;}}}t->rchild = q;q->rchild = q->lchild = NULL;que[rear++] = q;}else{t->rchild = NULL;printf("找到序号为:%d\n",x);break;}//M,leftif(flag){merge6(t->shuzu,n);q = (BTNode*)malloc(sizeof(BTNode));q->data = x;for(i=0;i<6;i++){q->shuzu[i]=n[i];}//flag=findFlag(n);if(!findSameFlag4(n)){x+=2;//v3.2版本修复bugcontinue;}else{for(i=1;i<ShuzuSize;i++){if(record[i][0]==0){for(j=0;j<6;j++){record[i][j]=n[j];}break;}}}t->lchild = q;q->rchild = q->lchild = NULL;que[rear++] = q;}else{t->lchild = NULL;printf("找到序号为:%d\n",x-1);break;}x+=2;}return bt;
}BTNode* CreateBiTree3(int n[12])//m12,由1~12演变输出到文件,层序创建二叉树
{static BTNode *t, *bt, *q;long x=1;int i,j;//1bt = (BTNode*)malloc(sizeof(BTNode));bt->data = 0;for(i=0;i<12;i++){bt->shuzu[i]=i+1;}for(j=0;j<12;j++){//将数组写入已打印队列,以便查找有无重复record[0][j]=j+1;}bt->rchild = bt->lchild = NULL;que[rear++] = bt;while(x<GuangduZize & front<rear){t = que[front];front++;//M,leftif(flag){merge(t->shuzu,n);q = (BTNode*)malloc(sizeof(BTNode));q->data = x;for(i=0;i<12;i++){q->shuzu[i]=n[i];}//flag=findFlag(n);if(!findSameFlag4(n)){x+=2;//v3.2版本修复bugcontinue;}else{for(i=1;i<ShuzuSize;i++){if(record[i][0]==0){for(j=0;j<12;j++){record[i][j]=n[j];}break;}}}t->lchild = q;q->rchild = q->lchild = NULL;que[rear++] = q;}else{t->lchild = NULL;printf("找到序号为:%d\n",x-1);break;}if(flag){invert(t->shuzu,n);q = (BTNode*)malloc(sizeof(BTNode));q->data = x+1;for(i=0;i<12;i++){q->shuzu[i]=n[i];}//flag=findFlag(n);if(!findSameFlag4(n)){x+=2;//v3.2版本修复bugcontinue;}else{for(i=1;i<ShuzuSize;i++){if(record[i][0]==0){for(j=0;j<12;j++){record[i][j]=n[j];}break;}}}t->rchild = q;q->rchild = q->lchild = NULL;que[rear++] = q;}else{t->rchild = NULL;printf("找到序号为:%d\n",x);break;}x+=2;}return bt;
}BTNode* CreateBiTree4(int n[12])//m12,由1~12演变输出到文件,层序创建二叉树
{static BTNode *t, *bt, *q;long x=1;int i,j;//1bt = (BTNode*)malloc(sizeof(BTNode));bt->data = 0;for(i=0;i<12;i++){bt->shuzu[i]=n[i];}for(j=0;j<12;j++){//将数组写入已打印队列,以便查找有无重复record[0][j]=n[i];}bt->rchild = bt->lchild = NULL;que[rear++] = bt;while(x<GuangduZize & front<rear){t = que[front];front++;//M,leftif(flag){merge(t->shuzu,n);q = (BTNode*)malloc(sizeof(BTNode));q->data = x;for(i=0;i<12;i++){q->shuzu[i]=n[i];}flag=findFlag(n);if(!findSameFlag4(n)){x+=2;//v3.2版本修复bugcontinue;}else{for(i=1;i<ShuzuSize;i++){if(record[i][0]==0){for(j=0;j<12;j++){record[i][j]=n[j];}break;}}}t->lchild = q;q->rchild = q->lchild = NULL;que[rear++] = q;}else{t->lchild = NULL;printf("找到序号为:%d\n",x-1);break;}if(flag){invert(t->shuzu,n);q = (BTNode*)malloc(sizeof(BTNode));q->data = x+1;for(i=0;i<12;i++){q->shuzu[i]=n[i];}flag=findFlag(n);if(!findSameFlag4(n)){x+=2;//v3.2版本修复bugcontinue;}else{for(i=1;i<ShuzuSize;i++){if(record[i][0]==0){for(j=0;j<12;j++){record[i][j]=n[j];}break;}}}t->rchild = q;q->rchild = q->lchild = NULL;que[rear++] = q;}else{t->rchild = NULL;printf("找到序号为:%d\n",x);break;}x+=2;}return bt;
}void DispBTNode(BTNode *b,FILE* fp){     //以括号表示法输出二叉树if(b!=NULL){//printf("\t%6d   ",b->data);fprintf(fp,"\t%6d   ",b->data);for(int i=0;i<6;i++){//12//printf("%2d ",b->shuzu[i]);fprintf(fp,"%2d ",b->shuzu[i]);}//printf("\r\n");fprintf(fp,"\n");if(b->lchild!=NULL || b->rchild!=NULL){//printf("(");fprintf(fp,"(");DispBTNode(b->lchild,fp);if(b->rchild!=NULL)//printf(",");fprintf(fp,",");DispBTNode(b->rchild,fp);//printf(")");fprintf(fp,")");}}
}void DispBTNode2(BTNode *b,FILE* fp){     //以括号表示法输出二叉树if(b!=NULL){printf("%d",b->data);fprintf(fp,"%d",b->data);//for(int i=0;i<12;i++){//   printf("%2d ",b->shuzu[i]);//  fprintf(fp,"%2d ",b->shuzu[i]);//}//printf("\r\n");//fprintf(fp,"\n");if(b->lchild!=NULL || b->rchild!=NULL){printf("(");fprintf(fp,"(");DispBTNode2(b->lchild,fp);if(b->rchild!=NULL)printf(",");fprintf(fp,",");DispBTNode2(b->rchild,fp);printf(")");fprintf(fp,")");}}
}void AllPath(BTNode *b){        //采用非递归方法输出从叶子结点到根结点的路径struct snode{BTNode *node;   //存放当前结点指针int parent;     //存放双亲结点在队列中的位置}Qu[MaxSize];   //定义顺序队列int front,rear,p;       //定义队头和队尾指针front=rear=-1;      //置队列为空队列rear++;Qu[rear].node=b;        //根结点指针进入队列Qu[rear].parent=-1;     //根结点没有双亲结点while(front<rear){      //队列不为空front++;b=Qu[front].node;       //队头出队列if(b->lchild==NULL && b->rchild==NULL){ //*b为叶子结点printf("%d到根结点路径:",b->data);p=front;while(Qu[p].parent!=-1){printf("%d ",Qu[p].node->data);p=Qu[p].parent;}printf("%d\n",Qu[p].node->data);}if(b->lchild!=NULL){    //左孩子入队列rear++;Qu[rear].node=b->lchild;Qu[rear].parent=front;}if(b->rchild!=NULL){    //右孩子入队列rear++;Qu[rear].node=b->rchild;Qu[rear].parent=front;}}
}
void AllPath1(BTNode *b,int path[],int pathlen){   //采用递归方法输出从叶子结点到根结点的路径int i;if(b!=NULL){if(b->lchild==NULL && b->rchild==NULL){ //*b为叶子结点printf("%d到根结点路径:%d ",b->data,b->data);for(i=pathlen-1;i>=0;i--)printf("%d ",path[i]);printf("\n");}else{path[pathlen]=b->data;  //将当前结点放入路径中pathlen++;AllPath1(b->lchild,path,pathlen);   //递归扫描左子树AllPath1(b->rchild,path,pathlen);   //递归扫描右子树pathlen--;}}
}
void LongPath(BTNode *b,int path[],int pathlen,int longpath[],int &longpathlen){  //求最长路径int i;if(b==NULL){if(pathlen>longpathlen){    //若当前路径更长,将路径保存在longpath中for(i=pathlen-1;i>=0;i--)longpath[i]=path[i];longpathlen=pathlen;}}else{path[pathlen]=b->data;      //将当前结点放入路径中pathlen++;      //路径长度增1LongPath(b->lchild,path,pathlen,longpath,longpathlen);  //递归扫描左子树LongPath(b->rchild,path,pathlen,longpath,longpathlen);  //递归扫描右子树pathlen--;      //恢复环境}
}
void DispLeaf(BTNode *b){   //输出叶子结点if(b!=NULL){if(b->lchild==NULL && b->rchild==NULL)printf("%d ",b->data);else{DispLeaf(b->lchild);DispLeaf(b->rchild);}}
}// 在二叉树(并不需要是排序二叉树)中查找value的节点,并返回指向该节点的指针,没找到返回NULL
Bitree getNodeByValue( Bitree root, int data )
{Bitree pRet = NULL;if( NULL == root ){printf("getNodeByValue func: err -1, NULL==root");return pRet;        }   if( root->data == data ){pRet = root;return pRet;}else{Bitree pLeftResult = NULL;Bitree pRightResult = NULL;if( root->lchild != NULL ){pLeftResult = getNodeByValue( root->lchild, data );}if( pLeftResult != NULL ) // 找到了{pRet = pLeftResult;return pRet;}if( root->rchild != NULL ){pRightResult = getNodeByValue( root->rchild, data );}if( pRightResult != NULL ) // 找到了{pRet = pRightResult;return pRet;}else{    return pRet;}}}//查找从根节点到pNode节点的路径
//返回0表示查找成功,-1表示查找失败
int getNodePathFromRoot1( Bitree root, Bitree pNode, vector<Bitree> &path )
{int ret = 0; if( NULL == root || NULL == pNode ){//printf("getNodePathFromRoot1 func: err -1, NULL == root || NULL == pNode");ret = -1;return ret;}if( root == pNode ) // 查找到了{path.push_back(root);return ret;}path.push_back(root);Bitree pleft = root->lchild;Bitree pright = root->rchild;int found = -1;if( pleft != NULL )  {int ret1 = getNodePathFromRoot1( pleft, pNode, path ); // 从左子树查找if( 0 == ret1 ){ret = ret1;return ret;}}if( pright != NULL ){int ret2 = getNodePathFromRoot1( pright, pNode, path ); // 从右子树查找if( 0 == ret2 ){ret = ret2;return ret;   }}path.pop_back(); // 左右子树都没有找到就弹出当前元素ret = -1;return ret; // 返回查找失败的标志}int breath_travel(Bitree pRoot,Queue *pQueue)
{if(!pRoot){return 0;}      enQueue(pQueue,pRoot);printf("_______________________\n");printf("breath begin,enter root:\n");while(ifEmpty(pQueue)!=0){QNode  *qNode  = deQueue(pQueue);//make suer every enQueue Node is not NULLif(qNode->t_node->lchild!=NULL)  enQueue(pQueue,qNode->t_node->lchild);if(qNode->t_node->rchild!=NULL)enQueue(pQueue,qNode->t_node->rchild);  //print the tree node valueprintf("%d ",qNode->t_node->data);}    printf("\n-----------\nbreath end!\n-----------\n");return 1;
}void DispBTNode3(BTNode *bt,FILE* fp){     //有问题未完成static Bitree nNode = NULL;static vector<Bitree> curPathe;long len;long ch;if(bt!=NULL){ch=bt->data;printf("%6d   ",ch);fprintf(fp,"%6d   ",ch);for(int i=0;i<12;i++){//12fprintf(fp,"%2d ",bt->shuzu[i]);}printf("\t");//得到路径nNode = getNodeByValue( bt, ch );getNodePathFromRoot1( bt, nNode, curPathe );len = curPathe.size();//for(i = len-1; i >0; --i )//{//printf("%c", (curPathe[i]->data)%2==0?'I':'M');//   fprintf(fp,"%c", (curPathe[i]->data)%2==0?'I':'M');//}//fprintf(fp,"\t");for(i = 0; i < len-1; ++i ){if(curPathe[i]->data<curPathe[i+1]->data){// & curPathe[i]->data+1!=curPathe[i+1]->data){fprintf(fp,"%ld ", curPathe[i]->data);}}fprintf(fp,"%ld\t", curPathe[len-1]->data);for(i = 1; i < len-1; ++i ){if(curPathe[i]->data<curPathe[i+1]->data){// & curPathe[i]->data+1!=curPathe[i+1]->data){fprintf(fp,"%c", (curPathe[i]->data)%2==0?'I':'M');}}fprintf(fp,"%c", (curPathe[len-1]->data)%2==0?'I':'M');printf("\n");fprintf(fp,"\n");if(bt->lchild!=NULL || bt->rchild!=NULL){DispBTNode3(bt->lchild,fp);if(bt->rchild!=NULL)DispBTNode3(bt->rchild,fp);}}
}void DispBTNode4(BTNode *b,FILE* fp){int i,res;long ch=0;Bitree pNode = NULL;while(ch<GuangduZize){pNode = getNodeByValue( b, ch );//while( ch && pNode ){//Bitree pNode = getNodeByValue( b, ch );vector<Bitree> curPath;//vector<Bitree> path = getNodePathFromRoot( root, pNode, curPath );res=getNodePathFromRoot1( b, pNode, curPath );if(res==0){fprintf(fp,"%ld\n",ch);long len = curPath.size();for(i = 0; i < len; ++i ){fprintf(fp,"%ld ", curPath[i]->data);}fprintf(fp,"\t");for(i = 1; i < len; ++i ){fprintf(fp,"%c", (curPath[i]->data)%2==0?'I':'M');}fprintf(fp,"\n");//ch = NULL;}}ch++;}
}void test(BTNode *b){int i;Bitree pNode = NULL;while(1){//char ch=getchar();long ch;printf("请输入序号:");fprintf(fp,"请输入序号:");scanf("%ld",&ch);fprintf(fp,"%ld\n",ch);pNode = NULL;pNode = getNodeByValue( b, ch );while( ch && pNode ){//Bitree pNode = getNodeByValue( b, ch );vector<Bitree> curPath;//vector<Bitree> path = getNodePathFromRoot( root, pNode, curPath );getNodePathFromRoot1( b, pNode, curPath );long len = curPath.size();for(i = 0; i < len; ++i ){printf("%ld ", curPath[i]->data);fprintf(fp,"%ld ", curPath[i]->data);}printf("\t");fprintf(fp,"\t");for(i = 1; i < len; ++i ){printf("%c", (curPath[i]->data)%2==0?'I':'M');fprintf(fp,"%c", (curPath[i]->data)%2==0?'I':'M');}printf("\r\n");fprintf(fp,"\r\n");ch = NULL;}fflush(fp);}
}int main(){static BTNode *b;//FILE* fp;static int path[MaxSize],longpath[MaxSize];long i,longpathlen=0;int n[12];flag=1;sameflag=1;fp=fopen("D:\\123.txt","w+");//CreateBTNode(b,"A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");//CreateBTNode(b,"1(2(4(7(12(19(28(39(52(67,68(84(101,102(117,118(131,132(143,144(161,162(169,170(175,176(179,180)))))))))),53(69(85,86(103,104(119,120(133,134(145,146(163,164(171,172(177,178)))))))))),40(54(70,71(87,88(105,106(121,122(135,136(147,148(165,166(173,174)))))))))),29(41(55,56(72,73(89,90(107,108(123,124(137,138(149,150(167,168)))))))))),20(30(42,43(57,58(74,75(91,92(109,110(125,126(139,140(151,152)))))))))),13(21(31,32(44,45(59,60(76,77(93,94(111,112(127,128(141,142)))))))))),8(14(22,23(33,34(46,47(61,62(78,79(95,96(113,114(129,130)))))))))),5(9(15,16(24,25(35,36(48,49(63,64(80,81(97,98(115,116)))))))))),3(6(10,11(17,18(26,27(37,38(50,51(65,66(82,83(99,100))))))))))");//CreateBTNode(b,"1(3(5(7(9(11(13(15(17(19(21(,22),20),18),16),14),12),10),8),6),4),2(23(25(27(29(31(33(35(37(39(41(,42),40),38),36),34),32),30),28),26),24)))");//1(3(5(7(9(11(13(15(17(19(21(,22),20),18),16),14),12),10),8),6),4),2(23(25(27(29(31(33(35(37(39(41(,42),40),38),36),34),32),30),28),26),24)))//CreateBTNode1(b);//先序创建二叉树//CreateBTNode2(b);//CreateBTNode3(b);printf("请不重复且随机的输入1~12:\n");fprintf(fp,"请不重复且随机的输入1~12:\n");fprintf(fp,"eg:1  2  3  4  5  6  7  8  9 10 11 12\n");fflush(fp);for(i=0;i<6;i++)//12{scanf("%d",&n[i]);}//CreateBTNode4(b,n);//CreateBTNode5(b,n);//CreateBTNode6(b,n);//CreateBTNode7(b,n);//b=CreateBiTree(n);//层序创建二叉树,更好,输入打乱后的数,排列成1~6b=CreateBiTree2(n);//输入1~6,生成txt文件用于比较//b=CreateBiTree3(n);//输入1~12,用于比较printf("二叉树b:\n");fprintf(fp,"二叉树b:\n");DispBTNode(b,fp);DispBTNode4(b,fp);printf("\n\n");printf("文件输出完毕!位置为D:\\123.txt\n");//printf("b的叶子结点:");DispLeaf(b);printf("\n\n");//printf("AllPath:\n");AllPath(b);printf("\n");//printf("AllPath1:\n");AllPath1(b,path,0);printf("\n");//LongPath(b,path,0,longpath,longpathlen);//printf("第一条最长路径长度:%d\n",longpathlen);//printf("第一条最长路径:");//for(i=longpathlen-1;i>=0;i--)//    printf("%d ",longpath[i]);//printf("\n");fflush(fp);/*Bitree pNode = NULL;while(1){//char ch=getchar();long ch;printf("请输入序号:");fprintf(fp,"请输入序号:");scanf("%ld",&ch);fprintf(fp,"%ld\n",ch);pNode = getNodeByValue( b, ch );while( ch && pNode ){//Bitree pNode = getNodeByValue( b, ch );vector<Bitree> curPath;//vector<Bitree> path = getNodePathFromRoot( root, pNode, curPath );getNodePathFromRoot1( b, pNode, curPath );long len = curPath.size();for(i = 0; i < len; ++i ){printf("%ld ", curPath[i]->data);fprintf(fp,"%ld ", curPath[i]->data);}printf("\t");fprintf(fp,"\t");for(i = 1; i < len; ++i ){printf("%c", (curPath[i]->data)%2==0?'I':'M');fprintf(fp,"%c", (curPath[i]->data)%2==0?'I':'M');}printf("\r\n");fprintf(fp,"\r\n");ch = NULL;}fflush(fp);}*/test(b);fclose(fp);return 0;
}

代码中为了简化调试,我曾使用过1-6,所以如果运行异常,可以尝试1-6。

java版本在处理内存和二叉树上更加简单:
BinaryTree.java

package javab;import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;public class BinaryTree {final static int MAXSIZE = 2000000;final static int GUANGDUSIZE = 80;final static int SHUZUSIZE = 100;static int record[][] = new int[SHUZUSIZE][4];static int flag;//find "  1  2  3  4  5  6  7  8  9 10 11 12"TreeNode root;public BinaryTree() {  root = null;  }  public int merge(int[] input, int[] output){output[0]=input[0];output[1]=input[11];output[2]=input[1];output[3]=input[10];output[4]=input[2];output[5]=input[9];output[6]=input[3];output[7]=input[8];output[8]=input[4];output[9]=input[7];output[10]=input[5];output[11]=input[6];return 1;}public int invert(int[] input, int[] output){int temp,k=0;merge(input, output);while(k<6)//12/2{temp=input[k];output[k]=input[11-k];//12-k-1output[11-k]=temp;//12-k-1k++;}return 1;}public int findFlag(int n[]){if(flag==0 | (n[0]==1 && n[1]==2 && n[2]==3 && n[3]==4 && n[4]==5)){return 0;}else{return 1;}}public int findSameFlag(int[] n){for(int i=0;i<SHUZUSIZE;i++){//fprintf(fp,"%3d\t%2d%2d%2d%2d%2d%2d%2d%2d%2d%2d%2d%2d\n",i,n[0],n[1],n[2],n[3],n[4],n[5],record[i][0],record[i][1],record[i][2],record[i][3],record[i][4],record[i][5]);if(n[0]==record[i][0] && n[1]==record[i][1] && n[2]==record[i][2] && n[3]==record[i][3] && n[4]==record[i][4]){return 0;}}return 1;}//层序创建树  //http://moonmonster.iteye.com/blog/2249490public void builderTree(int[] n) {  TreeNode[] tree = new TreeNode[100];  int[] tmpsz = new int[12];int[] tmpsz2=new int[12];int index = 0;  while (index<GUANGDUSIZE) {  TreeNode temp = null;if (index == 0) {  root = new TreeNode(index+1, n); //root.shuzu = n;tree[index] = root;  //for(int i:tree[index].shuzu){// System.out.println(i);//}} else {  if (index % 2 == 0) {  tmpsz2=tree[index/2-1].shuzu;invert(tmpsz2, tmpsz);if(findSameFlag(tmpsz)==0){index++;continue;}else{for(int i=1;i<SHUZUSIZE;i++){if(record[i][0]==0){record[i]=n;break;}}temp = new TreeNode(index+1, tmpsz);//temp.shuzu = tmpsz;tree[index] = temp;  tree[index / 2-1].rightChild = temp;  }} else {  System.out.println("tree");tmpsz2=tree[index/2].shuzu;for(int i=0;i<12;i++){System.out.print(tmpsz2[i]+" ");}merge(tmpsz2,tmpsz);System.out.println("tmpsz");for(int i=0;i<12;i++){System.out.print(tmpsz[i]+" ");}if(findSameFlag(tmpsz)==0){index++;}else{for(int i=1;i<SHUZUSIZE;i++){if(record[i][0]==0){record[i]=n;break;}}temp = new TreeNode(index+1, tmpsz);//temp.shuzu = tmpsz;System.out.println("");tree[index] = temp;  tree[index / 2].leftChild = temp;  }}  }  index++;  }  }  //层序输出//https://blog.csdn.net/snow_7/article/details/51815787public void levelIterator(TreeNode root){if(root == null){return ;}LinkedList<TreeNode> queue = new LinkedList<TreeNode>();TreeNode current = null;queue.offer(root);//将根节点入队while(!queue.isEmpty()){current = queue.poll();//出队队头元素并访问//System.out.print(current.data +"-->");System.out.print(current.data +"  ");for(int i=0;i<12;i++){System.out.print(current.shuzu[i]+" ");}System.out.println("");if(current.leftChild != null)//如果当前节点的左节点不为空入队{queue.offer(current.leftChild);}if(current.rightChild != null)//如果当前节点的右节点不为空,把右节点入队{queue.offer(current.rightChild);}}System.out.println("");}//求根节点到叶子节点路径//https://blog.csdn.net/xiezongsheng1990/article/details/79574892public List<String> binaryTreePaths(TreeNode root) {List<String> list=new ArrayList<String>();Queue<TreeNode> qNode=new LinkedList<TreeNode>();Queue<String> qStr=new LinkedList<String>();if (root==null) return list;qNode.add(root);qStr.add("");while(!qNode.isEmpty()) {TreeNode curNode=qNode.remove();String curStr=qStr.remove();if (curNode.leftChild==null && curNode.rightChild==null) list.add(curStr+curNode.data);if (curNode.leftChild!=null) {qNode.add(curNode.leftChild);qStr.add(curStr+curNode.data+"->");}if (curNode.rightChild!=null) {qNode.add(curNode.rightChild);qStr.add(curStr+curNode.data+"->");}}return list;}/*public BinaryTree(int data){setTree(data);}public BinaryTree(int data,BinaryTree left,BinaryTree right){setTree(data,left,right);}void setTree(int data){root=new TreeNode(data);}void setTree(int data,BinaryTree left,BinaryTree right){root=new TreeNode(data);if(left!=null){root.setleftChild(left.root);}if(right!=null){root.setrightChild(right.root);}}*/
}

Tree.java

package javab;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.List;
import java.util.Scanner;public class Tree {final static int MAXSIZE = 2000000;final static int GUANGDUSIZE = 80;final static int SHUZUSIZE = 100;static int record[][] = new int[SHUZUSIZE][4];static int flag;//find "  1  2  3  4  5  6  7  8  9 10 11 12"public static void main(String[] args) throws FileNotFoundException {// TODO Auto-generated method stub//BinaryTree tree1=create();File f = new File("output.txt");FileOutputStream fileOutputStream = new FileOutputStream(f,false);//true可以追加到文件output.txt的末尾,没有true 每次新建一个output.txtPrintStream printStream = new PrintStream(fileOutputStream);// 重新分配“标准”输出流System.setOut(printStream);BinaryTree tree1 = new BinaryTree();Scanner sc = new Scanner(System.in);int[] input = new int[12];for(int i=0;i<12;i++){input[i]=Integer.parseInt(sc.next());}tree1.builderTree(input);tree1.levelIterator(tree1.root);List<String> list = tree1.binaryTreePaths(tree1.root);for(String str:list){System.out.println(str);}
//      int[] a=new int[12];
//      int[] b=new int[12];
//      for(int i=0;i<12;i++){//          a[i]=i+1;
//      }
//      tree1.invert(a, b);
//      tree1.merge(b, a);
//      for(int i=0;i<12;i++){//          System.out.println(a[i]);
//      }}
}

Treenode.java

package javab;//https://www.cnblogs.com/MISSCHEN/p/3788093.html
public class TreeNode {//final static int MAXSIZE = 2000000;//final static int GUANGDUSIZE = 80;//final static int SHUZUSIZE = 100;//static int flag;int data;int[] shuzu = new int[12];TreeNode leftChild,rightChild,next;public TreeNode(int data,int[] shuzu){this.data=data;this.shuzu = shuzu;}public TreeNode(int data,TreeNode left,TreeNode right){leftChild=left;rightChild=right;}public int getdata(){return data;}public void setleftChild(TreeNode left){leftChild=left;}public void setrightChild(TreeNode right){rightChild=right;}}

这个项目是想研究魔方中的最短路径和有哪些路径是重复的。在数学中这属于群论的问题(散在单群)。这是个简易版的解魔方程序,如果刚入门解不了魔方,可以先解这个,有了思路可以尝试更复杂的二阶,三阶魔方。

解类魔方算法(以C和JAVA为基础)相关推荐

  1. 解魔方算法/Thislethwaite解魔方算法/降群法

    0.前言 主流的魔方解法,从入门的层先法,到进阶的CFOP.桥式乃至盲拧,都是从部分到整体的思路,逐块逐层还原魔方.但是Thislethwaite法不同,Thislethwaite法从整体出发,不断降 ...

  2. 【java进阶06:数组】使用一维数组模拟栈数据结构 使用二维数组模拟酒店,酒店管理系统 Arrays工具类 冒泡排序算法、选择排序算法、二分法

    目录 数组 二维数组 总结 作业 Arrays工具类 数组 数组总结 及 静态初始化一维数组 /* Array:1.java语言中的数组是一种引用数据类型,不属于基本数据类型,数组的父类是Object ...

  3. java ML回归预测_ML之回归预测:利用九大类机器学习算法对无人驾驶汽车系统参数(2018年的data,18+2)进行回归预测值VS真实值...

    ML之回归预测:利用九大类机器学习算法对无人驾驶汽车系统参数(2018年的data,18+2)进行回归预测值VS真实值 目录 输出结果 数据的初步查验:输出回归目标值的差异 The max targe ...

  4. java实现apriori算法_七大经典、常用排序算法的原理、Java 实现以及算法分析

    0. 前言 大家好,我是多选参数的程序员,一个正再 neng 操作系统.学数据结构和算法以及 Java 的硬核菜鸡.数据结构和算法是我准备新开的坑,主要是因为自己再这块确实很弱,需要大补(残废了一般) ...

  5. 算法和数据结构(Java语言)

    算法和数据结构(Java语言) 持续更新中- 线性结构和非线性结构 线性结构 线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系 线性结构有两种不同的存储结构,即顺序存储结构和链式 ...

  6. 算法竞赛中的JAVA使用笔记

    算法竞赛中的JAVA使用笔记 算法竞赛中的JAVA使用笔记 输入与输出 基本输入 输入挂 输出 控制台输入输出重定向到文件 大整数与高精度 大整数BigInteger 高精度BigDecimal 高精 ...

  7. 算法竞赛中的JAVA使用笔记(转载)

    本篇JAVA笔记转自豪爷的博客(戳这里有传送门). 以下是原文: 输入与输出 基本输入 较复杂的输入 输入挂 输出 控制台输入输出重定向到文件 大整数与高精度 大整数BigInteger 高精度Big ...

  8. DL之MaskR-CNN:基于类MaskR-CNN算法(RetinaNet+mask head)利用数据集(resnet50_coco_v0.2.0.h5)实现目标检测和目标图像分割(语义分割)

    DL之MaskR-CNN:基于类MaskR-CNN算法(RetinaNet+mask head)利用数据集(resnet50_coco_v0.2.0.h5)实现目标检测和目标图像分割(语义分割) 目录 ...

  9. 【算法知识】详解直接插入排序算法

    前言 已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 在玩扑克牌的时候,我们抽到一张牌的时候,都是将它插入到当前手中牌的合适位置的. 如下图: (上图来自算法导论) 直接插入排序 ...

最新文章

  1. Python3中的字符串
  2. 多ajax请求的各类解决方案(同步, 队列, cancel请求)
  3. java+JBroFuzz对restful api进行fuzz测试
  4. python webqq机器人_python模拟开发WebQQ(二)
  5. SAP UI5库对浏览器类型检测的实现
  6. mysqlbinlog工具_mysqlbinlog命令详解 Part 1-实验环境准备
  7. Intent实现页面跳转
  8. 帆软报表邮箱验证码登录
  9. 揭秘!开源软件背后的神秘组织
  10. 换了马甲也能认出“你” | 有了这个数据集,AI有望揪出变种勒索软件
  11. 前端取色器 FSCapture
  12. 蓝牙驱动卸载后自动安装_外星人的控制中心下载,安装及常见问题处理方法
  13. 租用服务器多开虚拟机,云服务器多开虚拟机
  14. 第一章、Zigbee模块的简介及特点
  15. 关于yolov5出现报错 KeyError: ‘copy_paste‘之类Key问题解决办法
  16. 爬取雪球网的新闻数据
  17. 深入理解设计模式-设计模式七大原则
  18. Python图像处理笔记——形态学处理(skimage.morphology)
  19. 学食品安全考计算机,食品卫生学考点总结.docx
  20. 7-114 用if-else语句编程百分制成绩转换为五分制成绩

热门文章

  1. 自学Java到底怎样才能入门?
  2. 怎么点亮段码屏_灰阶显示段码液晶屏及其灰阶显示方法与流程
  3. 从2021年财报看京东的新型实体势能
  4. 计算机英语五人对话,一篇5人英语小对话,-五人英语对话加翻译-井睾品同学
  5. c和java哪个难_为什么说 C 语言比 Java 难?
  6. Android 屏幕录像教程
  7. logstash之ruby模块
  8. 电脑图标变白怎么办?
  9. 【小红书排名规则】社区规则、账号权重、笔记权重和推荐规则
  10. 产品经理?一个新职位