解类魔方算法(以C和JAVA为基础)

这是15年前,环球科学杂志上的一篇文章,作者写了一个类似简单魔方的小游戏:M12
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 empty
           pQueue->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-1
		output[11-k]=temp;//12-k-1
		k++;
	}
	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-1
		output[5-k]=temp;//12-k-1
		k++;
	}
	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;
	//1
    bt = (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,left
		if(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版本修复bug
				continue;
			}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版本修复bug
				continue;
			}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;
	//1
    bt = (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,left
		if(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版本修复bug
				continue;
			}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版本修复bug
				continue;
			}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;
	//1
    bt = (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版本修复bug
				continue;
			}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,left
		if(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版本修复bug
				continue;
			}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;
	//1
    bt = (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,left
		if(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版本修复bug
				continue;
			}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版本修复bug
				continue;
			}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;
	//1
    bt = (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,left
		if(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版本修复bug
				continue;
			}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版本修复bug
				continue;
			}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++;      //路径长度增1
        LongPath(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 NULL
     if(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 value
     printf("%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++){//12
			fprintf(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~6
	b=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-1
			output[11-k]=temp;//12-k-1
			k++;
		}
		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/2249490
    public 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/51815787
    public 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/79574892
    public 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.txt
		PrintStream 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;
	}
	
}

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值