| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 983 人关注过本帖
标题:递归及非递归汉诺塔
只看楼主 加入收藏
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
结帖率:94.64%
收藏
 问题点数:0 回复次数:4 
递归及非递归汉诺塔
程序代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void  move(char, char);
void  hanoi1(int, char, char, char);
void  hanoi2(int, char, char, char);
int   get_dis_size(int);
int * calc_dis_value(int, int *, int);
void  even_next(char *, char *, char, char, char, int);
void  odd_next(char *, char *, char, char, char, int);

int main(void)
{
    int n;
   
    scanf("%d", &n);
    hanoi2(n, 'A', 'B', 'C');
   
    return 0;
}

void move(char from, char to)
{
    printf("%c -> %c\n", from, to);
}

void hanoi1(int n, char a, char b, char c)
{
    if(n == 1)
        move(a, c);
    else if(n > 1) {
        hanoi1(n - 1, a, c, b);
        move(a, c);
        hanoi1(n - 1, b, a, c);
    }
}

void hanoi2(int n, char a, char b, char c)
{   
    int   size    = get_dis_size(n);
    int * dis_arr = (int *)calloc(size, sizeof(int));
    int   i, j    = 0;
    int   p          = (int)pow(2, n);
    char  prev[2];
   
    if(size || n > 0) {
        calc_dis_value(n, dis_arr, size);
        if(n % 2)
            move(a, c);
        else
            move(a, b);
        prev[0] = a;
        for(i = 2; i < p; i++) {
            if(i % 2)
                odd_next(prev + 0, prev + 1, a, b, c, n);
            else
                even_next(prev + 0, prev + 1, a, b, c, n);
            if(i == dis_arr[j]) {
                move(prev[1], prev[0]);
                j++;
            } else {
                move(prev[0], prev[1]);
            }
        }
    }
   
    free(dis_arr);
}

int get_dis_size(int n)
{
    int dis_size = 1;
    int i;
   
    if(n < 3)
        return 0;
    else if(n > 3)
        for(i = 4; i <= n; i++)
            dis_size = i % 2 ? dis_size * 2 + 1 : dis_size * 2;
   
    return dis_size;
}

int * calc_dis_value(int n, int * dis_arr, int size)
{
    int i, j, k, p, tmp;
   
    if(n > 2) {
        for(i = 0, j = 3; i < size; j++) {
            p = (int)pow(2, j);
            if(j % 2) {
                tmp = i;
                dis_arr[i++] = p / 2;
                for(k = tmp - 1; k >= 0; k--)
                    dis_arr[i++] = p - dis_arr[k];
            } else {
                for(k = i - 1; k >= 0; k--)
                    dis_arr[i++] = p - dis_arr[k];
            }
        }
    }
   
    return dis_arr;
}

void odd_next(char * prev1, char * prev2, char a, char b, char c, int n)
{
    if(n % 2) {
        if(*prev2 == a)
            *prev1 = b;
        else if(*prev2 == b)
            *prev1 = c;
        else
            *prev1 = a;
    } else {
        if(*prev2 == a)
            *prev1 = c;
        else if(*prev2 == b)
            *prev1 = a;
        else
            *prev1 = b;
    }
}

void even_next(char * prev1, char * prev2, char a, char b, char c, int n)
{
    if(n % 2) {
        if(*prev1 == a)
            *prev2 = b;
        else if(*prev1 == b)
            *prev2 = c;
        else
            *prev2 = a;
    } else {
        if(*prev1 == a)
            *prev2 = c;
        else if(*prev1 == b)
            *prev2 = a;
        else
            *prev2 = b;
    }
}
/*
    n = 1            n = 2           n = 3            n = 4            n = 5             n = 6             n = 7
1   A -> C           A -> B          A -> C           A -> B           A -> C            A -> B            A -> C
2                    A -> C          A -> B           A -> C           A -> B            A -> C            A -> B
3                    B -> C          C -> B           B -> C           C -> B            B -> C            C -> B
4                                    C -> A (A -> C)  B -> A (A -> B)  C -> A (A -> C)   B -> A (A -> B)   C -> A (A -> C)
5                                    B -> A           C -> A           B -> A            C -> A            B -> A
6                                    B -> C           C -> B           B -> C            C -> B            B -> C
7                                    A -> C           A -> B           A -> C            A -> B            A -> C
8                                                     A -> C           A -> B            A -> C            A -> B
9                                                     B -> C           C -> B            B -> C            C -> B
10                                                    B -> A           C -> A            B -> A            C -> A
11                                                    C -> A           B -> A            C -> A            B -> A
12                                                    C -> B (B -> C)  B -> C (C -> B)   C -> B (B -> C)   B -> C (C -> B)
13                                                    A -> B           A -> C            A -> B            A -> C
14                                                    A -> C           A -> B            A -> C            A -> B
15                                                    B -> C           C -> B            B -> C            C -> B
16                                                                     C -> A (A -> C)   B -> A (A -> B)   C -> A (A -> C)
17                                                                     B -> A            C -> A            B -> A
18                                                                     B -> C            C -> B            B -> C
19                                                                     A -> C            A -> B            A -> C
20                                                                     A -> B (B -> A)   A -> C (C -> A)   A -> B (B -> A)
21                                                                     C -> B            B -> C            C -> B
22                                                                     C -> A            B -> A            C -> A
23                                                                     B -> A            C -> A            B -> A
24                                                                     B -> C            C -> B            B -> C
25                                                                     A -> C            A -> B            A -> C
26                                                                     A -> B            A -> C            A -> B
27                                                                     C -> B            B -> C            C -> B
28                                                                     C -> A (A -> C)   B -> A (A -> B)   C -> A (A -> C)
29                                                                     B -> A            C -> A            B -> A
30                                                                     B -> C            C -> B            B -> C
31                                                                     A -> C            A -> B            A -> C
32                                                                                       A -> C            A -> B
33                                                                                       B -> C            C -> B
34                                                                                       B -> A            C -> A
35                                                                                       C -> A            B -> A
36                                                                                       C -> B (B -> C)   B -> C (C -> B)
37                                                                                       A -> B            A -> C
38                                                                                       A -> C            A -> B
39                                                                                       B -> C            C -> B
40                                                                                       B -> A            C -> A
41                                                                                       C -> A            B -> A
42                                                                                       C -> B            B -> C
43                                                                                       A -> B            A -> C
44                                                                                       A -> C (C -> A)   A -> B (B -> A)
45                                                                                       B -> C            C -> B
46                                                                                       B -> A            C -> A
47                                                                                       C -> A            B -> A
48                                                                                       C -> B (B -> C)   B -> C (C -> B)
49                                                                                       A -> B            A -> C
50                                                                                       A -> C            A -> B
51                                                                                       B -> C            C -> B
52                                                                                       B -> A (A -> B)   C -> A (A -> C)
53                                                                                       C -> A            B -> A
54                                                                                       C -> B            B -> C
55                                                                                       A -> B            A -> C
56                                                                                       A -> C            A -> B
57                                                                                       B -> C            C -> B
58                                                                                       B -> A            C -> A
59                                                                                       C -> A            B -> A
60                                                                                       C -> B (B -> C)   B -> C (C -> B)
61                                                                                       A -> B            A -> C
62                                                                                       A -> C            A -> B
63                                                                                       B -> C            C -> B
64                                                                                                         C -> A (A -> C)
65                                                                                                         B -> A
66                                                                                                         B -> C
67                                                                                                         A -> C
68                                                                                                         A -> B (B -> A)
69                                                                                                         C -> B
70                                                                                                         C -> A
71                                                                                                         B -> A
72                                                                                                         B -> C
73                                                                                                         A -> C
74                                                                                                         A -> B
75                                                                                                         C -> B
76                                                                                                         C -> A (A -> C)
77                                                                                                         B -> A
78                                                                                                         B -> C
79                                                                                                         A -> C
80                                                                                                         A -> B (B -> A)
81                                                                                                         C -> B
82                                                                                                         C -> A
83                                                                                                         B -> A
84                                                                                                         B -> C (C -> B)
85                                                                                                         A -> C
86                                                                                                         A -> B
87                                                                                                         C -> B
88                                                                                                         C -> A
89                                                                                                         B -> A
90                                                                                                         B -> C
91                                                                                                         A -> C
92                                                                                                         A -> B (B -> A)
93                                                                                                         C -> B
94                                                                                                         C -> A
95                                                                                                         B -> A
96                                                                                                         B -> C
97                                                                                                         A -> C
98                                                                                                         A -> B
99                                                                                                         C -> B
100                                                                                                        C -> A (A -> C)
101                                                                                                        B -> A
102                                                                                                        B -> C
103                                                                                                        A -> C
104                                                                                                        A -> B
105                                                                                                        C -> B
106                                                                                                        C -> A
107                                                                                                        B -> A
108                                                                                                        B -> C (C -> B)
109                                                                                                        A -> C
110                                                                                                        A -> B
111                                                                                                        C -> B
112                                                                                                        C -> A (A -> C)
113                                                                                                        B -> A
114                                                                                                        B -> C
115                                                                                                        A -> C
116                                                                                                        A -> B (B -> A)
117                                                                                                        C -> B
118                                                                                                        C -> A
119                                                                                                        B -> A
120                                                                                                        B -> C
121                                                                                                        A -> C
122                                                                                                        A -> B
123                                                                                                        C -> B
124                                                                                                        C -> A (A -> C)
125                                                                                                        B -> A
126                                                                                                        B -> C
127                                                                                                        A -> C

可以看出移动的过程是一个交叉顺序链,可是在有些位置会被断开:
n = 1: 无
n = 2: 无
n = 3: 4
n = 4: 4 12
n = 5: 4 12 16 20 28
n = 6: 4 12 16 20 28 36 44 48 52 60
n = 7: 4 12 16 20 28 36 44 48 52 60 64 68 76 80 84 92 100 108 112 116 124
(括号中是正确的顺序),我们只需要在断开的时候把过程反过来就行了,可以看出这些断开点有规律可寻,如当n = 7时,4 + 124 = 2 ^ 7,12 + 116 = 2 ^ 7,16 + 112 = 2 ^ 7...
64 + 64 = 2 ^ 7,这是一些以2 ^ (n - 1)对称的数。但这里有一个问题,就是如果n是奇数,那么 2 ^ (n - 1)存在,而n是偶数2 ^ (n - 1)不存在,需要在一个循环里判断。
*/

hanoi1是汉诺塔递归移动函数。
hanoi2是汉诺塔迭代移动函数。

[ 本帖最后由 lz1091914999 于 2011-8-23 17:18 编辑 ]
搜索更多相关主题的帖子: color 
2011-08-23 17:04
雾雨淼淼
Rank: 2
来 自:甘肃金昌
等 级:论坛游民
帖 子:85
专家分:89
注 册:2010-8-17
收藏
得分:0 
不好意思,程序太长
2011-08-23 17:06
雾雨淼淼
Rank: 2
来 自:甘肃金昌
等 级:论坛游民
帖 子:85
专家分:89
注 册:2010-8-17
收藏
得分:0 
可以百度一下
2011-08-23 17:07
shy8549
Rank: 1
等 级:新手上路
帖 子:6
专家分:1
注 册:2011-8-13
收藏
得分:0 
学习一下。
2011-08-23 17:14
zanzan1986
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:100
专家分:140
注 册:2011-2-22
收藏
得分:0 
我就是从汉诺塔才懂得递归的原理,并得到灵活运用。
2011-08-23 17:55
快速回复:递归及非递归汉诺塔
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.035723 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved