欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c語言循環(huán)加數(shù)組實現(xiàn)漢諾塔問題

 更新時間:2022年01月28日 10:29:52   作者:用戶882121311605lv-1  
本文主要介紹了c語言循環(huán)加數(shù)組實現(xiàn)漢諾塔問題,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

簡介

漢諾塔問題是學(xué)數(shù)據(jù)結(jié)構(gòu)與算法的時候會遇到的問題,相信來看本文的讀者應(yīng)該都對漢諾塔問題有基本的了解,理論上所有的遞歸都可以改成循環(huán),常規(guī)的做法是借助堆棧,但是我一想好像用循環(huán)加數(shù)組也可以實現(xiàn),于是就有了本文,實現(xiàn)聲明,本文最后出來的算法效率不高的,比直接用遞歸實現(xiàn)還要差很多,追求算法效率的同學(xué)就不用看這個了。
題目:假設(shè)有3個柱子,分別為A、B、C,A柱子上有數(shù)量為n個的空心圓盤,從上到下序號分別為1...n,要求把A柱子中的n個圓盤移動到C柱中,且序號大的盤子必須在在需要小的圓盤下方。
思路:如果只有1個圓盤需要移動,則直接從A柱移動到C柱,如果有n個圓盤(n>1)需要移動,則需要先把n-1個圓盤從A柱移動到B柱,再把第n個圓盤從A柱移動到C柱,最后把原來的n-1個圓盤從B柱移動到C柱。

例如:

將1個圓盤從A柱移動到C柱只需要1個步驟:

1. 把圓盤1從A移動到C

將2個圓盤從A柱移動到C柱需要3個步驟:

1. 把圓盤1從A移動到B
2. 把圓盤2從A移動到C
3. 把圓盤1從B移動到C

將3個圓盤從A柱移動到C柱需要7個步驟:

1. 把圓盤1從A移動到C
2. 把圓盤2從A移動到B
3. 把圓盤1從C移動到B
4. 把圓盤3從A移動到C
5. 把圓盤1從B移動到A
6. 把圓盤2從B移動到C
7. 把圓盤1從A移動到C

遞歸的漢諾塔解法(c語言)

可以看出下面的遞歸算法的時間復(fù)雜度為O(2^n),因為存在有調(diào)用2^n-2次遞歸調(diào)用和1次原生printf;而空間復(fù)雜度為O(n),因為運行時棧中最多會同時保存n個函數(shù)的調(diào)用信息。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void towers(int n, char from, char to, char aux);
int main() {
?? ?towers(3, 'A', 'C', 'B');
?? ?return 0;
}

void showMove (int order, char from, char to) {
?? ?printf("move disk %d from %c to %c\n", order, from, to);
}

void towers(int n, char from, char to, char aux) {
?? ?if (n==1) {
?? ??? ?showMove(n, from, to);
?? ??? ?return;
?? ?}
?? ?towers(n-1, from, aux, to);
? ? ? ? showMove(n, from, to);
?? ?towers(n-1, aux, to, from);
}

解釋一下代碼中參數(shù)的含義,void towers(int n, char from, char to, char aux)的意思是把n個圓盤從from柱子移動到to柱子,中間可以借用aux柱子。

分析一下上面的遞歸執(zhí)行過程:

我們已經(jīng)知道把1個圓盤從from移動到to的步驟是showMove(1, from, to);

而把2個圓盤從from移動到to的步驟是,先照著移動1個圓盤的操作,把前面1個圓盤從from移動到aux,再把第2個圓盤從from移動到to,最后按照移動1個圓盤的操作,把剛才的1個圓盤從aux移動到to。

同理,把3個圓盤從from移動到to的步驟是,先照著移動2個圓盤的操作,把前面2個圓盤從from移動到aux,再把第3個圓盤從from移動到to,最后按照移動2個圓盤的操作,把剛才的2個圓盤從aux移動到to。

所以,把n個圓盤的操作從from移動到to的步驟是,先照著移動n-1個圓盤的操作,把前面n-1個圓盤從from移動到aux,再把第n個圓盤從from移動到to,最后按照移動n-1個圓盤的操作,把剛才的n-1個圓盤從aux移動到to。

因此,我們可以記錄移動1個圓盤的步驟,來得到移動2個圓盤的步驟,通過移動2個圓盤的步驟來得到移動3個圓盤的步驟,...最后得到移動n個圓盤的步驟。經(jīng)過分析可以知道移動n個圓盤一共會有2^n-1個步驟

循環(huán)實現(xiàn)漢諾塔問題(c語言)

為了代碼更加易懂,這里寫了注釋,修改了部分變量命名,統(tǒng)一用數(shù)組保存步驟集合,最后才輸出。
可以看出這個算法的時間復(fù)雜度還是O(2^n),一共會執(zhí)行2^(n+1)-1次setMoveAction語句和2^n-1次,printf語句,比起直接用遞歸還要復(fù)雜一些,而空間復(fù)雜度也是O(2^n),屬于沒什么用的算法,就是隨便寫寫。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void towers(int n, char from, char to, char aux);
int main()
{
?? ?towers(3, 'A', 'C', 'B');
?? ?return 0;
}

void showMove(int order, char from, char to)
{
?? ?printf("move disk %d from %c to %c\n", order, from, to);
}

typedef struct
{
?? ?int order;
?? ?char from;
?? ?char to;
} MoveAction;

void setMoveAction(MoveAction *p, int order, char from, char to)
{
?? ?p->order = order;
?? ?p->from = from;
?? ?p->to = to;
}

char compare_map(char c, char left, char right) {
?? ?if (c == left) {
?? ??? ?return right;
?? ?} else if (c == right) {
?? ??? ?return left;
?? ?}
?? ?return c;
}

void towers(int n, char from, char to, char aux)
{
?? ?MoveAction *actions, action;
?? ?int i, k, size;
?? ?char f, t;

?? ?actions = (MoveAction *)calloc(pow(2, n - 1) - 1, sizeof(MoveAction));
?? ?setMoveAction(&actions[0], 1, from, to);
?? ?size = 1;

?? ?for (i = 2; i <= n; i++)
?? ?{
?? ??? ?//本次循環(huán)會將把i個盤子從from移動到to的步驟記錄到actions數(shù)組中
?? ??? ?// 設(shè)size是把i-1個盤子從from移動到to的步驟數(shù),
?? ??? ?// 則本次循環(huán)中集合{actions[x] | 0 <= x <= size -1 }就是size是把i-1個盤子從from移動到aux的步驟集合,
?? ??? ?//而action[size]是把第i個盤子從from移到to,
?? ??? ?//而集合{actions[x] | size + 1 <= x <= 2*size }就應(yīng)該是把i-1個盤存從aux移動到to的步驟集合

?? ??? ?// 倒序,先求解集合{actions[x] | size + 1 <= x <= 2*size }
?? ??? ?for (k = 0; k < size; k++)
?? ??? ?{
?? ??? ??? ?action = actions[k];
?? ??? ??? ?f = compare_map(action.from, from, aux);
?? ??? ??? ?t = compare_map(action.to, from, aux);
?? ??? ??? ?setMoveAction(&actions[k + size + 1], action.order, f, t);
?? ??? ?}
?? ??? ?// 求解action[size]
?? ??? ?setMoveAction(&actions[size], i, from, to);
?? ??? ?// 求解集合{actions[x] | 0 <= x <= size -1 }
?? ??? ?for (k = 0; k < size; k++)
?? ??? ?{
?? ??? ??? ?action = actions[k];
?? ??? ??? ?f = compare_map(action.from, to, aux);
?? ??? ??? ?t = compare_map(action.to, to, aux);
?? ??? ??? ?setMoveAction(&actions[k], action.order, f, t);
?? ??? ?}
?? ??? ?size = size * 2 + 1;
?? ?}

?? ?for (i = 0; i < size; i++)
?? ?{
?? ??? ?showMove(actions[i].order, actions[i].from, actions[i].to);
?? ?}
}

到此這篇關(guān)于c語言循環(huán)加數(shù)組實現(xiàn)漢諾塔問題的文章就介紹到這了,更多相關(guān)c語言 漢諾塔內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++ stringstream格式化輸出輸入詳情

    C++ stringstream格式化輸出輸入詳情

    這篇文章主要介紹了C++ stringstream格式化輸出輸入,首先string str; cin>>str;遇到空格結(jié)束;于是乎產(chǎn)生了getline(),可與得到一行字符串;空格自動去掉,下面來看看文章的詳細(xì)內(nèi)容,需要的小伙伴可以參考一下
    2021-11-11
  • C++ ffmpeg硬件解碼的實現(xiàn)方法

    C++ ffmpeg硬件解碼的實現(xiàn)方法

    這篇文章主要介紹了C++ ffmpeg硬件解碼的實現(xiàn),對FFmpeg多媒體解決方案中的視頻編解碼流程進行研究。為嵌入式多媒體開發(fā)提供參考,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • c++實現(xiàn)超簡單的貪吃蛇游戲?qū)嵗榻B

    c++實現(xiàn)超簡單的貪吃蛇游戲?qū)嵗榻B

    大家好,本篇文章主要講的是c++實現(xiàn)超簡單的貪吃蛇游戲?qū)嵗榻B,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • 關(guān)于C++的.cpp文件運行全過程

    關(guān)于C++的.cpp文件運行全過程

    這篇文章主要介紹了C++的.cpp文件運行全過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C++ OpenCV生成蒙太奇圖像的示例詳解

    C++ OpenCV生成蒙太奇圖像的示例詳解

    圖片的蒙太奇效果,一般稱為馬賽克圖。由很多小圖拼接成一個大圖。這篇文章主要為大家介紹如何利用C++ OpenCV實現(xiàn)生成蒙太奇圖像,感興趣的可以了解一下
    2022-01-01
  • 詳解C語言中的memset()函數(shù)

    詳解C語言中的memset()函數(shù)

    這篇文章主要介紹了C語言中的memset()函數(shù),包括其與memcpy()函數(shù)的區(qū)別,需要的朋友可以參考下
    2015-08-08
  • linux之a(chǎn)wk命令的用法

    linux之a(chǎn)wk命令的用法

    awk是一個非常棒的數(shù)字處理工具。相比于sed常常作用于一整行的處理,awk則比較傾向于將一行分為數(shù)個“字段”來處理。運行效率高,而且代碼簡單,對格式化的文本處理能力超強
    2013-10-10
  • C/C++中的內(nèi)存管理小結(jié)

    C/C++中的內(nèi)存管理小結(jié)

    這篇文章主要介紹了C/C++中的內(nèi)存管理小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • C++之內(nèi)存泄漏排查詳解

    C++之內(nèi)存泄漏排查詳解

    這篇文章主要介紹了c++ 如何排查內(nèi)存泄漏,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下,希望能夠給你帶來幫助
    2021-10-10
  • C語言程序中結(jié)構(gòu)體的內(nèi)存對齊詳解

    C語言程序中結(jié)構(gòu)體的內(nèi)存對齊詳解

    這篇文章主要為大家詳細(xì)介紹了C語言程序中結(jié)構(gòu)體的內(nèi)存對齊的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的參考價值,感興趣的小伙伴可以了解一下
    2022-11-11

最新評論