zoukankan      html  css  js  c++  java
  • 汉诺塔的非递归算法和递归算法--C语言

    题目:

    即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”)

    解法一、非递归算法

    所有的汉诺塔移动可以总结为重复的两步,我们假设现在最小的圆盘在a柱子上,柱子为a,b,c

    第一步:将最小圆盘移动到下一个柱子上,也就是b

    第二步:对a柱子和c柱子进行顶上最小的元素进行判断,把小一点的那个圆盘移动到大一点的那个圆盘(有空则摞在空柱子上)。

    重复上述两步,直到两根柱子均空结束。

    注意:这样得到的最后的答案不一定是摞在c上,如果N是偶数将摞在b上,所以如果N是偶数我们就令第二个柱子为c,第三个柱子为b,这样就一定最后是摞在c上的。

     1 #include <stdio.h>
     2 #include <malloc.h>
     3 #define ElemType char
     4 #define ERROR -1
     5 #define max 1000
     6 typedef enum {false,true
     7              } bool;
     8 typedef struct {
     9     char *Data;
    10     int Top;
    11     int MaxSize;
    12 }*Stack;
    13 Stack a[4];
    14 char c[4]= {'q','a','b','c'};//柱子编号从1开始 
    15 Stack CreateStack(int maxsize) {
    16     Stack S=(Stack)malloc(sizeof(Stack));
    17     S->Data=(ElemType*)malloc(sizeof(ElemType)*maxsize);
    18     S->MaxSize=maxsize;
    19     S->Top=-1;
    20     return S;
    21 }
    22 bool IsEmpty(Stack S) {
    23     if(S->Top==-1)
    24         return true;
    25     return false;
    26 }
    27 bool IsFull(Stack S) {
    28     if(S->Top==S->MaxSize-1)
    29         return true;
    30     return false;
    31 }
    32 bool Push(Stack S,ElemType X) {
    33     if(IsFull(S))
    34         return false;
    35     S->Data[++S->Top]=X;
    36     return true;
    37 }
    38 ElemType Pop(Stack S) {
    39     if(IsEmpty(S))
    40         return ERROR;
    41     return S->Data[S->Top--];
    42 }
    43 ElemType GetTop(Stack S) {
    44     return S->Data[S->Top];
    45 }
    46 
    47 bool move(int before,int after) {
    48     if(IsEmpty(a[before]))
    49         return false;
    50     if(!IsEmpty(a[after])) {
    51         if(GetTop(a[after])<GetTop(a[before]))
    52             return false;
    53         }
    54     Push(a[after],Pop(a[before]));
    55     printf("%c -> %c
    ",c[before],c[after]);
    56 }
    57 int main() {
    58     int n;
    59     scanf("%d",&n);
    60     int i;
    61     for(i=0; i<4; i++) {
    62         a[i]=CreateStack(max);
    63     }
    64     if(n%2==1) {
    65         c[2]='c';
    66         c[3]='b';
    67     }
    68     for(i=0; i<n; i++) {
    69         Push(a[1],n-i);
    70     }
    71     int cnt=0;
    72     while(++cnt) {
    73         move((cnt-1)%3+1,(cnt)%3+1);
    74         if(!move((cnt-1)%3+1,(cnt+1)%3+1)&&!move((cnt+1)%3+1,(cnt-1)%3+1))
    75             break;
    76     }
    77 }

    解法二、递归算法

    第1步:将n-1个盘从a->b; hannoi(n-1,a,b,c)

    第2步:将第n个盘从a->c;(递归出口) printf("a -> c")

    第3步:再将n-1个盘从b->c;hannoi(n-1,b,c,a)

    注意传入参数后 a='a',b='c',c='b';

    #include <stdio.h>
    int hanoi(int n,char a,char b,char c) {
        if(n>0) {
            hanoi(n-1,a,c,b);
            printf("%c -> %c
    ",a,b);
            hanoi(n-1,c,b,a);
        }
    
    }
    int main() {
        int n;
        scanf("%d",&n);
        hanoi(n,'a','c','b');
        return 0;
    }
    勤能补拙,熟能生巧
  • 相关阅读:
    超级楼梯
    hdu1040
    hdu2033(惭愧)
    hdu2032杨辉三角
    hdu1013Digital Roots
    hdu2031
    Linux信号(signal) 机制分析
    android init重启service(进程)
    [android] init进程 .rc文件中service、action的parsing
    oom_adj
  • 原文地址:https://www.cnblogs.com/snzhong/p/12409835.html
Copyright © 2011-2022 走看看