1. 程式人生 > >用遞迴和非遞迴兩種辦法計算Hanoi問題

用遞迴和非遞迴兩種辦法計算Hanoi問題

#include "stdafx.h"
#include <iostream.h>
#include <stack>
#include <map>
using namespace std;

void Move(int nFrom,int nTo);
void Hanoi1(int nNums,int nFrom,int nThrough,int nTo);
void Hanoi2(int nNums,int nFrom,int nThrough,int nTo);

int main(int argc, char* argv[])
{
 cout<<"begining...."<<endl;
 Hanoi1(4,1,2,3);
 cout<<"begining2...."<<endl;
 Hanoi2(4,1,2,3);
 return 0;
}

void Move(int nFrom,int nTo)
{
 cout<< "move from peg "<<nFrom << " to peg " << nTo << endl;
}

void Hanoi1(int nNums,int nFrom,int nThrough,int nTo)
{
 if(1==nNums) {
  Move(nFrom,nTo);
 }
 else {
  Hanoi1(nNums-1,nFrom,nTo,nThrough);
  Move(nFrom,nTo);
  Hanoi1(nNums-1,nThrough,nFrom,nTo);
 }
}

void Hanoi2(int nNums,int nFrom,int nThrough,int nTo)
{
 stack<int> peg[3]; 
 map<int,int> amap;
 amap.insert(map<int,int>::value_type(0,nFrom));
 amap.insert(map<int,int>::value_type(1,nThrough));
 amap.insert(map<int,int>::value_type(2,nTo));
 int i;
 for(i=nNums;i>=1;i--) peg[0].push(i);

 int nDirection=(nNums % 2)?-1:1;
 bool bSmallMove=true;
 int nSmallest=0;
 int nSmallestNext;
 while (peg[2].size()!=nNums)
 {
  if (bSmallMove)
  {
   nSmallestNext=(nSmallest+nDirection+3) % 3;
   peg[nSmallest].pop();
   peg[nSmallestNext].push(1);
   Move(amap[nSmallest],amap[nSmallestNext]);
   nSmallest=nSmallestNext;
  }
  else
  {
   int k,indice[2],count; 
   count=0;
   for(k=0;k<3;k++)
   {
    if (peg[k].empty()) {
     indice[count]=k;
     count++;
     continue;
    }
    if (peg[k].top()==1) continue;
    indice[count]=k;
    count++;
   }

   if( !( peg[indice[0]].empty() || peg[indice[1]].empty() ) )
   {
    if (peg[indice[0]].top()>peg[indice[1]].top())
    {
     k=indice[0];
     indice[0]=indice[1];
     indice[1]=k;
    }

   }
   else if (peg[indice[0]].empty())
   {
    k=indice[0];
    indice[0]=indice[1];
    indice[1]=k;
   }
   
   k=peg[indice[0]].top();
   peg[indice[0]].pop();
   peg[indice[1]].push(k);
   Move(amap[indice[0]],amap[indice[1]]);   
   
  }
  bSmallMove=!bSmallMove;
 } //while
}

 

相關推薦

辦法計算Hanoi問題

#include "stdafx.h"#include <iostream.h>#include <stack>#include <map>using namespace std; void Move(int nFrom,int nTo);void Hanoi1(int

一列數字的規則如下;1,1,2,3,5,8,13,21,34........ 求第30位數字是多少,方法演算法實現

斐波納契數列(Fibonacci Sequence),又稱黃金分割數列。在數學上,斐波納契數列以如下被以遞迴的方法定義:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)在現代物理、準晶體結構、化學等領域,斐波納契數列都有直接的應用,現在我從演算法的角度,利用遞迴和非

求第n個斐波那契數(分別方法求解)

斐波那契數列指的是這樣一個數列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55……這個數列從第3項開始,每一項都等於前兩項之和。 這裡分別用遞迴和非遞迴的方法實現: 遞迴 #define _CRT_SECURE_NO_WARNINGS 1 #include&l

猴子吃桃問題,方法

猴子吃桃問題:猴子第一天摘下若干個桃子,當即吃了一半,還不過癮,又多吃了一個 第二天早上又將剩下的桃子吃掉一半,又多吃了一個。以後每天早上都吃了前一天剩下的一半零一個。到第10天早上想再吃時,見只剩下一個桃子了。求第一天共摘了多少。   public class Test{ &nb

二叉樹的前序,中序,後序遍歷。實現

#include<iostream> #include<stack> using namespace std; #define MAX 100 typedef struct Tree{ int data; Tree*lchild; Tree*rchild; }

實現斐波那契數列

斐波那契數列(Fibonacci sequence),又稱黃金分割數列、因數學家列昂納多·斐波那契(Leonardoda Fibonacci)以兔子繁殖為例子而引入,故又稱為“兔子數列”,指的是這樣一個數列:1、1、2、3、5、8、13、21、34、……在數學上,斐波納契數列

[C語言]的方法在楊氏矩陣中查詢

從楊氏矩陣中查詢數字,以及調整奇數位於陣列的前半部分 //從楊氏矩陣中查詢數字 //1.從右上角開始找,如果要找的值大於當前值,向下找,否則,向左找,方向確定 //2.從左下角開始找,如果要找的值大於當前值,向右找,否則,向上找,方向確定 //---->最

3.1分別方式實現二叉樹先序、中序後序遍歷

題目 用遞迴和非遞迴方式,分別按照二叉樹先序、中序和後序列印所有的節點。 首先給出二叉樹節點結構定義: public class BinaryTreeNode { //二叉樹節點 private int data; private Bi

漢諾塔的改編題(棧求解,分別

限制不能從最左側的塔直接移動到最右側,也不能從最右側直接移動到最左側,而是必須經過中間,求當塔有N層的時候,列印最優移動過程和最優移動總步數 例如:當塔為兩層時,最上層的塔記為1,最下層的塔記為2,則

N個臺階,一次可以走一步或者步,求走這n個臺階有多少方法(實現)

1、遞迴實現 <pre name="code" class="cpp">///遞迴方法 int Fibonacci(unsigned int N) { if(N<=2)

合併個有序連結串列(

合併兩個有序連結串列 #include <stdio.h> #include <stdlib.h> typedef char linktype; typedef struct linklist{ linktype data

shell指令碼語言實現一個斐波那契數列的版本

程式碼: #!/bin/bash -x #第一種寫法 #first=1 #second=1 #last=1 # #if [ $1 -le 2 ];then # echo 1 #fi # #i=3 #while [ $i -le $1 ] #do # let last=

[c語言]求第n個斐波那契數

程式碼 //1.1遞迴求第n個斐波那契數 #include<stdio.h> int fib(int n) { if(n<=2) return 1; else return fib(n-1)+fib(n-2); } int main

(1)建立二叉樹的二叉連結串列。 (2)寫出對二叉連結串列儲存的二叉樹進行先序、中序後序遍歷的遞迴和非遞迴演算法。 (3)寫出對二叉連結串列儲存的二叉樹進行層次遍歷演算法。 (4)求二叉樹的所有葉子及結點總數。

(1)建立二叉樹的二叉連結串列。 (2)寫出對用二叉連結串列儲存的二叉樹進行先序、中序和後序遍歷的遞迴和非遞迴演算法。 (3)寫出對用二叉連結串列儲存的二叉樹進行層次遍歷演算法。(4)求二叉樹的所有葉子及結點總數。 include<stdio.h> #inclu

連結串列反轉(使用方式)

#include <stdio.h> #include <iostream> using namespace std; //連結串列的資料結構 typedef struct lNode { int data; struc

資料結構方法實現二分查詢法

       二分查詢法說的通俗一點就是折半查詢,每查詢一次,所對應的元素就會減少一半,所以這種方法的優點就是比較的次數少,查詢的速度快。但其最大的缺點就是插入資料比較困難。所以在面對資料一直會發生變動的列表,就不推薦用二分查詢法了。        那麼下面就來實際介紹一下

練習題013:二分查詢(方法)

題目:用遞迴和非遞迴兩種方法實現二分查詢 非遞迴法: int binary_search(int *arr, int lenth, int key) { assert(arr != NU

分別採用方式編寫個函式,求一棵二叉樹中葉子節點個數

#include #include #define MAXSIZE 50 typedef char datatype; typedef struct node { datatype data; struct node *lchild,*rchild; } bintnode,*bintre

python實現個數最大公約數、最小公倍數

    最大公約數和最小公倍數的概念大家都很熟悉了,在這裡就不多說了,今天這個是因為做題的時候遇到了所以就寫下來作為記錄,也希望幫到別人,下面是程式碼: #!/usr/bin/env python #coding:utf-8 from fractions import gc

java實現連結串列逆序

傳統的逆序連結串列方法是使用三個指標來記錄節點的狀態,防止連結串列斷裂。Node節點public class Node { private int data; private Node next; public Node(int data){