漢諾塔非遞歸java算法(java實現漢諾塔遞歸)

本文目錄一覽:

用java編寫hanoi塔的非遞歸算法。

這是個好問題,很少看到有人寫漢諾塔的非遞歸…其實只要先寫出遞歸,然後把遞歸的每一步要做的事情記錄在一個棧裡面就可以了

public class Test {

private static void emitStep(int source, int dest) {

System.out.println(source + ” – ” + dest);

}

static class Step {

Step(int n, int s, int d, int t) {

this.n = n;

source = s;

dest = d;

temp = t;

}

int n, source, dest, temp;

}

private static void hanoi(int n, int source, int dest, int temp) {

java.util.StackStep steps = new java.util.StackStep();

steps.add(new Step(n, source, dest, temp));

while (steps.empty() == false) {

Step step = steps.pop();

if (step.n == 1) {

emitStep(step.source, step.dest);

continue;

}

steps.push(new Step(step.n – 1, step.temp, step.dest, step.source));

steps.push(new Step(1, step.source, step.dest, 0));

steps.push(new Step(step.n – 1, step.source, step.temp, step.dest));

}

}

public static void main(String[] args) {

hanoi(3, 1, 3, 2);

}

}

漢諾塔非遞歸的寫法

以前寫過

#include iostream

using namespace std;

//圓盤的個數最多為64

const int MAX = 64;

//用來表示每根柱子的信息

struct st{

int s[MAX]; //柱子上的圓盤存儲情況

int top; //棧頂,用來最上面的圓盤

char name; //柱子的名字,可以是A,B,C中的一個

int Top()//取棧頂元素

{

return s[top];

}

int Pop()//出棧

{

return s[top–];

}

void Push(int x)//入棧

{

s[++top] = x;

}

} ;

long Pow(int x, int y); //計算x^y

void Creat(st ta[], int n); //給結構數組設置初值

void Hannuota(st ta[], long max); //移動漢諾塔的主要函數

int main(void)

{

int n;

cin n; //輸入圓盤的個數

st ta[3]; //三根柱子的信息用結構數組存儲

Creat(ta, n); //給結構數組設置初值

long max = Pow(2, n) – 1;//動的次數應等於2^n – 1

Hannuota(ta, max);//移動漢諾塔的主要函數

system(“pause”);

return 0;

}

void Creat(st ta[], int n)

{

ta[0].name = ‘A’;

ta[0].top = n-1;

//把所有的圓盤按從大到小的順序放在柱子A上

for (int i=0; in; i++)

ta[0].s[i] = n – i;

//柱子B,C上開始沒有沒有圓盤

ta[1].top = ta[2].top = 0;

for (int i=0; in; i++)

ta[1].s[i] = ta[2].s[i] = 0;

//若n為偶數,按順時針方向依次擺放 A B C

if (n%2 == 0)

{

ta[1].name = ‘B’;

ta[2].name = ‘C’;

}

else //若n為奇數,按順時針方向依次擺放 A C B

{

ta[1].name = ‘C’;

ta[2].name = ‘B’;

}

}

long Pow(int x, int y)

{

long sum = 1;

for (int i=0; iy; i++)

sum *= x;

return sum;

}

void Hannuota(st ta[], long max)

{

int k = 0; //累計移動的次數

int i = 0;

int ch;

while (k max)

{

//按順時針方向把圓盤1從現在的柱子移動到下一根柱子

ch = ta[i%3].Pop();

ta[(i+1)%3].Push(ch);

cout ++k “: ”

“Move disk ” ch ” from ” ta[i%3].name

” to ” ta[(i+1)%3].name endl;

i++;

//把另外兩根柱子上可以移動的圓盤移動到新的柱子上

if (k max)

{ //把非空柱子上的圓盤移動到空柱子上,當兩根柱子都為空時,移動較小的圓盤

if (ta[(i+1)%3].Top() == 0 ||

ta[(i-1)%3].Top() 0

ta[(i+1)%3].Top() ta[(i-1)%3].Top())

{

ch = ta[(i-1)%3].Pop();

ta[(i+1)%3].Push(ch);

cout ++k “: ” “Move disk “

ch ” from ” ta[(i-1)%3].name

” to ” ta[(i+1)%3].name endl;

}

else

{

ch = ta[(i+1)%3].Pop();

ta[(i-1)%3].Push(ch);

cout ++k “: ” “Move disk “

ch ” from ” ta[(i+1)%3].name

” to ” ta[(i-1)%3].name endl;

}

}

}

}

誰會漢諾塔非遞歸的編程(java),並真正了解含義

public class Hannuota {

private int n;//儲存盤子個數

public Hannuota(int n){

this.n = n;

}

public void function(){

//初始化三個柱子,A是開始堆滿盤子的柱子,C是目標柱子

Pillar a = new Pillar(n,n,”A”);

Pillar b = new Pillar(n,”B”);

Pillar c = new Pillar(n,”C”);

//把三個柱子按順序排好,詳見後面的算法那裡的解釋

Pillar[] pillars = new Pillar[3];

pillars[0] = a;

if(n%2==0){

pillars[1] = b;

pillars[2] = c;

}else{

pillars[1] = c;

pillars[2] = b;

}

//開始移動,k用來計數,移動次數為2^n-1,至於為什麼,我不太清楚,

//反正有人證明過。i是用來保存最小那個盤子正在哪跟柱子上的。

int i=0;

for(int k=0;k(int)Math.pow(2, n)-1;){

int min;

//將最小的盤子順時針移動一個柱子

min = pillars[i%3].Pop();

pillars[(i+1)%3].Push(min);

System.out.println(pillars[i%3]+”-“+pillars[(i+1)%3]);

k++;

i++;

//這個IF好像可以不要,當時寫的,後面忘了刪除。

if(k(int)Math.pow(2, n)-1){

//如果,剩下兩根柱子中,某一根為空,則一定是非空那根中最上面個盤子

//移動到空的那個柱子上。若兩根都不為空,則把編號小的一個盤子

//移動到另外跟柱子上

if(!pillars[(i-1)%3].isEmpty()(pillars[(i+1)%3].isEmpty()||pillars[(i+1)%3].Top()pillars[(i-1)%3].Top())){

min=pillars[(i-1)%3].Pop();

pillars[(i+1)%3].Push(min);

System.out.println(pillars[(i-1)%3]+”-“+pillars[(i+1)%3]);

}else{

min=pillars[(i+1)%3].Pop();

pillars[(i-1)%3].Push(min);

System.out.println(pillars[(i+1)%3]+”-“+pillars[(i-1)%3]);

}

k++;

}

}

}

//主函數,用來測試的。3表示3個盤子。

public static void main(String args[]){

new Hannuota(3).function();

}

}

class Pillar{//構造一個新類,表示柱子,實際是當一個棧在用

private int[] s;

private int top;

private String name;

public String toString(){

return name;

}

//這個構造函數用來構造BC兩個柱子,下面那個用來構造柱子A。其實也可以寫成一個構造函數。

public Pillar(int max,String name){

s = new int[max];

top = -1;

this.name = name;

for(int i=0;i s[i] = max+1;

}

}

public Pillar(int n,int max,String name){

s = new int[max];

top = n-1;

this.name = name;

for(int i=0;i s[i] = max – i;

}

}

//這後面這些就是棧的基本方法了,不用介紹了吧

public boolean isEmpty(){

return top==-1?true:false;

}

public int Top (){

return s[top];

}

public int Pop(){

return s[top–];

}

public void Push(int x){

s[++top] = x;

}

}

算法是這個

首先容易證明,當盤子的個數為n時,移動的次數應等於2^n – 1。

首先把三根柱子按順序排成品字型,把所有的圓盤按從大到小的順序放在柱子A上。

根據圓盤的數量確定柱子的排放順序:若n為偶數,按順時針方向依次擺放 A B C;

若n為奇數,按順時針方向依次擺放 A C B。

(1)按順時針方向把圓盤1從現在的柱子移動到下一根柱子,即當n為偶數時,若圓盤1在柱子A,則把它移動到B;

若圓盤1在柱子B,則把它移動到C;若圓盤1在柱子C,則把它移動到A。

(2)接着,把另外兩根柱子上可以移動的圓盤移動到新的柱子上。

即把非空柱子上的圓盤移動到空柱子上,當兩根柱子都非空時,移動較小的圓盤

這一步沒有明確規定移動哪個圓盤,你可能以為會有多種可能性,其實不然,可實施的行動是唯一的。

(3)反覆進行(1)(2)操作,最後就能按規定完成漢諾塔的移動。

這玩意要非遞歸真麻煩。需不需要加點注釋?

原創文章,作者:CYX7P,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/127705.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
CYX7P的頭像CYX7P
上一篇 2024-10-03 23:16
下一篇 2024-10-03 23:16

相關推薦

  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • 蝴蝶優化算法Python版

    蝴蝶優化算法是一種基於仿生學的優化算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化算法Python版…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Python實現爬樓梯算法

    本文介紹使用Python實現爬樓梯算法,該算法用於計算一個人爬n級樓梯有多少種不同的方法。 有一樓梯,小明可以一次走一步、兩步或三步。請問小明爬上第 n 級樓梯有多少種不同的爬樓梯…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29

發表回復

登錄後才能評論