22
2023
03

汉诺塔任意阶任意状态求解c语言版

之前用flash做了汉诺塔自动求解 。

阶数大了,flash计算太慢,所以用c语言写了一份。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

struct Node;
struct Triangle;
typedef struct Node {
	char value;
	char fullValue[20];
	Triangle* triangle;
	
	Node* left;
	Node* right;
	Node* parent;
} Node;

typedef struct Triangle {
	Node* head;
	Node* left;
	Node* right;
} Triangle;

void nodeFlip(Node* node);
void nodeTurnLeft(Node* node);
void nodeTurnRight(Node* node);
void triFlip(Triangle* tri);
void triTurnLeft(Triangle* tri);
void triTurnRight(Triangle* tri);
Triangle* triClone(Triangle* source);
void nodeClone(Node* target, Node* source);
void nodePrepare(Node* node, char* pre);
void triPrepare(Triangle* tri, char* pre);
void nodeSetLeft(Node* node, Node* left);
void nodeSetLeft(Node* node, Node* left);
void appendChar(char* s, char c);

Triangle* pTri;

int getNum(int n) {
	if(n == 1){
		return 1;
	}
	return 1 + 3 * (getNum(n - 1));
}


void nodeFlip(Node* node){
	if(node->triangle != NULL){
		triFlip(node->triangle);
	}
}

void nodeTurnLeft(Node* node){
	if(node->triangle != NULL){
		triTurnLeft(node->triangle);
	}
}

void nodeTurnRight(Node* node){
	if(node->triangle != NULL){
		triTurnRight(node->triangle);
	}
}

void triFlip(Triangle* tri) {
	Node* temp = tri->left;
	tri->left = tri->right;
	tri->right = temp;
	
    nodeFlip(tri->head);
	nodeFlip(tri->left);
	nodeFlip(tri->right);
}

void triTurnLeft(Triangle* tri) {
	Node* temp = tri->head;
	tri->head = tri->right;
	tri->right = tri->left;
	tri->left = temp;
	
	nodeTurnLeft(tri->head);
	nodeTurnLeft(tri->left);
	nodeTurnLeft(tri->right);
}

void triTurnRight(Triangle* tri) {
	Node* temp = tri->head;
	tri->head = tri->left;
	tri->left = tri->right;
	tri->right = temp;
	
	nodeTurnRight(tri->head);
	nodeTurnRight(tri->left);
	nodeTurnRight(tri->right);
}

void nodeClone(Node* target, Node* source){
	target->value = source->value;
	if(source->triangle != NULL) {
		target->triangle = triClone(source->triangle);
	}
}

Triangle* triClone(Triangle* source){
	Triangle* tri = pTri++;
	
	nodeClone(tri->head, source->head);
	nodeClone(tri->left, source->left);
	nodeClone(tri->right, source->right);
	
	return tri;
}

Node* leafHead(Node* node){
	if(node->triangle == NULL){
		return node;
	}
	return leafHead(node->triangle->head);
}

Node* leafLeft(Node* node){
	if(node->triangle == NULL){
		return node;
	}
	return leafLeft(node->triangle->left);
}

Node* leafRight(Node* node){
	if(node->triangle == NULL){
		return node;
	}
	return leafRight(node->triangle->right);
}

void appendChar(char* s, char c){
	int len = strlen(s);
	s[len] = c;
	s[len + 1] = '\0';
}

void nodePrepare(Node* node, char* pre){
	strcpy(node->fullValue, pre);
	appendChar(node->fullValue, node->value);
	
	if(node->triangle != NULL){
		triPrepare(node->triangle, node->fullValue);
	}
}

void nodeSetLeft(Node* node, Node* left){
	node->left = left;
	left->parent = node;
}

void nodeSetRight(Node* node, Node* right){
	node->right = right;
	right->parent = node;
}

void triPrepare(Triangle* tri, char* pre){
	nodePrepare(tri->head, pre);
	nodePrepare(tri->left, pre);
	nodePrepare(tri->right, pre);
	
	nodeSetLeft(leafLeft(tri->head), leafHead(tri->left));
	nodeSetRight(leafRight(tri->head), leafHead(tri->right));
}

void nodeWalk(Node* node){
	if(node->left == NULL && node->right == NULL){
		do{
			printf("->");
			printf(node->fullValue);
			node = node->parent;
		} while(node != NULL);
		printf("\n");
		return;
	}
	if(node->left != NULL){
		nodeWalk(node->left);
	}
	if(node->right != NULL){
		nodeWalk(node->right);
	}
}

void nodeInit(Node* node){
	node->triangle = NULL;
	node->left = NULL;
	node->right = NULL;
	node->parent = NULL;
}

int main(int argc, char *argv[]){
	
	int a; 
	if(argc == 2){
		a = atoi(argv[1]);
		// printf("%d\n", a);
		// return 0;
	} else {
		printf("Please enter the Hanoi Tower order:");
		scanf("%d",&a); 
	}
	
	clock_t start,end;
    start = clock();
	
	int n = a;
	printf("%d\n", n);
	int m = getNum(n);
	printf("%d\n", m);
	
	Triangle tris[m];
	Node nodes[m*3];
	printf("%d\n", sizeof(tris));
	printf("%d\n", sizeof(nodes));
	pTri = tris;
	
	int j = 0;
	for(int i = 0; i < m; i++){
		Triangle* tri = &(tris[i]);
		tri->head = &(nodes[j]);
		tri->left = &(nodes[j+1]);
		tri->right = &(nodes[j+2]);
		j+=3;
		tri->head->value = 'C';
		tri->left->value = 'B';
		tri->right->value = 'A';
		
		nodeInit(tri->head);
		nodeInit(tri->left);
		nodeInit(tri->right);
	}
	
	
	Triangle* root = pTri++;
	
	for(int i = 1; i < n; i++) {
		Triangle* tri = pTri++;
		
		triFlip(root);
		tri->head->triangle = root;
		
		tri->left->triangle = triClone(root);
		triTurnRight(tri->left->triangle);
		
		tri->right->triangle = triClone(root);
		triTurnLeft(tri->right->triangle);
		
		root = tri;
	}
	
	triPrepare(root, "");
	Node* rNode = leafHead(root->head);
	nodeWalk(rNode);
	
	end = clock();
    double duration =(double)(end-start)/CLOCKS_PER_SEC;
    printf("use time:%f s\n",duration);
	
	return 0;
}


c语言写得少,可能写的不太好,但是c语言确实快。

附件中有代码,exe文件,和1-9阶汉诺塔的自动求解数据。

可以直接运行hanoi.exe,然后输入阶数;也可以直接带参数运行,如:hanoi.exe 5;如果要输出结果可以运行:hanoi.exe 5 >hanoi5.txt


源码打包下载

« 上一篇下一篇 »

相关文章:

汉诺塔自动求解  (2023-3-15 9:1:50)

汉诺塔  (2023-3-7 14:19:22)

电路方程求解-列表法  (2021-6-23 14:1:55)

c语言贪食蛇  (2016-1-27 15:34:12)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。