遞歸和分治思想及其應用

目錄

  • 遞歸和分治思想
  • 一些實例
    • 逆序輸出字符串
    • 查找數組元祖是否存在
    • 漢諾塔問題
    • 八皇后問題
  • 更多:

遞歸和分治思想

如果可以使用迭代,盡量別使用遞歸。由編譯原理可以知道,每次自調用的時候,計算機都需要保存在調用,浪費時間空間。當然,迭代是當我們知道循環次數的時候。而當我們不知道循環次數,比如說對于文件夾和文件進行遍歷,不知道深度的情況下,我們就需要遞歸來實現。

顯然,遞歸是先解決小的問題,這種思想是分治思想。根據具體需求,來決定是否使用遞歸。

遞歸要注意:

  • 結構是選擇結構,而迭代是循環結構
  • 必須有基線條件和遞歸條件,防止出現死循環
  • 如果知道循環次數的話,盡量使用遞歸
  • 對于某些編程式函數,有對于尾遞歸的迭代優化
  • 遞歸邏輯更容易理解

一些實例

逆序輸出字符串

#include<iostream>
using namespace std;void print(){char a;cin>>a;if(a!='#') print(); // 不是停止符,先自調用 if(a!='#') cout<<a; //在回來的時候,打印自己的字符 
}
int main(){print();return 0;
}

查找數組元祖是否存在

很多時候我們需要查找一個數組中是否有一個元素。如果使用迭代,肯定十分簡單,時間復雜度為O(n)。

此時,如果使用分而治之的思想,我們可以使用二分法來進行查找。不論多大的數據,時間復雜度顯著降低為O(log_2 n)。也就是說一個大小為123456789的數組,使用迭代,我們需要123456789個時間單位。但是二分法只需要27次。

實現思路:

  1. 首先轉化的思想對數組進行排序。如果不排序,那么low和high就沒有意義了。
  2. 再用迭代進行二分
#include<iostream>
#include<algorithm>
using namespace std;
const int SIZE = 5;
const int NONE = -1;
//二分查找并且返回element的位置,沒查找到則返回NONE
template<class T>
int BinFind(T *arr,int low,int high,T elem){  int mid;if(low>high)return NONE;else{mid = (low+high)/2;if(arr[mid] == elem)return mid;else if(elem>arr[mid])return BinFind(arr,mid+1,high,elem);elsereturn BinFind(arr,low,mid-1,elem);}
}
int main(){int *arr = new int [SIZE];cout<<"請輸入"<<SIZE<<"個數據:"; for(int i=0;i<SIZE;++i)cin>>arr[i];sort(arr,arr+SIZE);int elem;cout<<"輸入您要查找的數據:"<<endl;cin>>elem; int index = BinFind(arr,0,SIZE-1,elem);if (index+1)cout<<"含有這個數據\n";elsecout<<"不含有這個數據";return 0;
}

漢諾塔問題

首先我們假設需要移動64層,那么思路如下(附截圖):

大問題

此時,需要解決兩個問題(附截圖):

總問題下的子問題

一直這樣類推,知道最后從begin(開始柱子)->end(目標柱子)。

按照第一張截圖,我們可以寫出來函數里面else的遞歸部分。并且,每次輸出的時候,就對應著思路里面的移動(而不是分治),此時step步數需要加+。

#include<iostream>
#include<algorithm>
using namespace std;
void Hanoi(int num,char begin,char by,char end,int &step){if(num==1){cout<<begin<<"-->"<<end<<endl;++step;}else{Hanoi(num-1,begin,end,by,step);cout<<begin<<"-->"<<end<<endl;++step;Hanoi(num-1,by,begin,end,step);}
}
int main(){int step = 0;int num;cout<<"漢諾塔層數是: ";cin>>num;Hanoi(num,'X','Y','Z',step);cout<<"一共有:"<<step<<"步數"<<endl; return 0;
}

八皇后問題

在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處于同一行、同一列或同一斜線上,問有多少種擺法。正規的方法是遞歸,如果不考慮效率,這里采用遞歸實現。假設從第一行開始,每一行都找到符合條件的一個位置,而條件就是新的一行的新位置符合要求,以此類推,就可以寫出來遞歸函數。

#include<iostream>
using namespace std;const int Q_NUM = 8;
int queens[Q_NUM][Q_NUM] = {0};
int RESULT = 0;void print(){for(int i=0;i<Q_NUM;++i){for (int j=0;j<Q_NUM;++j)cout<<queens[i][j]<<" ";cout<<endl;}cout<<endl<<endl;
}
bool IfQueen(int row,int col){if(row==0){//當第一行時候,隨便擺放 queens[row][col] = 1;return true;}/**************其他時候,需要考慮上面的同一列、左上角斜線、右上角斜線,以下分別實現*****/ for(int i=0;i<row;++i)if(queens[i][col]==1)return false;for (int i=row-1,j = col-1;i>=0 && j>=0;--i,--j)if(queens[i][j]==1)return false;for(int i=row-1,j=col+1;i>=0 && j<Q_NUM;--i,++j)if(queens[i][j]==1)return false;/******當所有情況都滿足********/queens[row][col] = 1;return true;
}
void Queen(int row){if(row==Q_NUM){ //注意row是從0開始到Q_NUM-1結束。這樣當row==Q_NUM時,已經排完所有情況 ++RESULT;   //這樣當row==Q_NUM時,已經排完所有情況,進行輸出就可以了。 print();return ;} for(int i=0;i<Q_NUM;++i){ //i代表列數 if(IfQueen(row,i)) //如果row行i列可以放得話,判斷下一行 Queen(row+1);queens[row][i] = 0; //重置為0,防止下次結果干擾 }
}int main(){Queen(0);cout<<"一共"<<RESULT<<"種擺法\n";return 0;
}

更多:

毫無疑問,遞歸以及分治思想還有很多用法:斐波那契數列、快速排序、文件查找、字典樹的建立等等。理論上遞歸可以解決任何問題,而作為我們只需要提供思路,其他的交給計算機解決。所以聽人說過計算機最適合解決遞歸問題。但是,有利有弊,遞歸同樣會消耗更多的內存。在初步實現階段,將大問題分而治之,分裝成遞歸函數,還是邏輯代碼化的最佳表達。


歡迎進一步交流本博文相關內容:

博客園地址 : http://www.cnblogs.com/AsuraDong/

CSDN地址 : http://blog.csdn.net/asuradong

也可以致信進行交流 : xiaochiyijiu@163.com

歡迎轉載 , 但請指明出處 ?:??)


轉載于:https://www.cnblogs.com/AsuraDong/p/7045141.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/258368.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/258368.shtml
英文地址,請注明出處:http://en.pswp.cn/news/258368.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AM+PM+FM基本調制原理及相關理論

總論&#xff1a; 調制信號&#xff1a; 模擬信號m(t)&#xff0c;可以是正弦波信號、方波信號等任意信號&#xff0c;又稱基帶信號 載波信號&#xff1a;一般為正弦波信號 已調信號&#xff1a; 幅度調制AM---A(t)隨m(t)成比例變化----線性調制 相位調制PM---隨m(t)成比…

unix網絡編程 的環境配置

<unix網絡編程> 的環境配置 首先在網上下載UNP的庫文件&#xff0c;然后就可以安裝學了。我的系統環境&#xff1a; 2.6.32-131.0.15.el6.i686 #1 SMP Sat Nov 12 17:30:50 CST 2011 i686 i686 i386 GNU/Linux LSB Version: :base-4.0-ia32:base-4.0-noarch:core-4.0-…

win32 api 文件操作!

CreateFile打開文件要對文件進行讀寫等操作&#xff0c;首先必須獲得文件句柄&#xff0c;通過該函數可以獲得文件句柄&#xff0c;該函數是通向文件世界的大門。ReadFile從文件中讀取字節信息。在打開文件獲得了文件句柄之后&#xff0c;則可以通過該函數讀取數據。WriteFile向…

小說里的lt什么意思_游戲cpdd網絡用語是什么意思 王者榮耀里很常見

[閩南網]隨著互聯網的發展&#xff0c;越來越多的流行語橫空出世&#xff0c;在網絡上得到廣泛使用。當一個網絡語流行的時候&#xff0c;不管在微博上還是貼吧里&#xff0c;都會看見和流行語有關的句子和表情包。眼下在各種游戲里&#xff0c;總是能看到游戲玩家們說“cpdd”…

POJ 1637 Sightseeing tour 混合圖歐拉回路存在性判斷

沒有想到網絡流還能解決這一類問題&#xff0c;完全想不到_ 一開始把所有的無向邊制定任意方向有當做有向邊看&#xff0c;然后統計每個點的入度和出度。以前有向圖的歐拉回路判定是每個點的入讀都等于出度&#xff0c;這樣可以保證可以回到起點&#xff0c;現在在一些邊可以調…

linux系統 硬鏈接和軟鏈接

背景&#xff1a; 當幾個用戶同在一個項目里工作時。經常須要共享文件。假設一個共享文件同一時候出如今屬于不同用戶的不同文件夾下。工作起來就非常方便。比如B和C文件夾下有一文件D是兩者都能夠訪問和改動的共享文件&#xff0c;這樣是非常方便&#xff0c;但也會有一些問題…

jquery純數字驗證

$(document).ready(function(){ //純數字驗證,只讓輸入數字,比如-號等都不然輸入。 $(#user-defined).unbind(); $(#user-defined).bind(keyup change,function () { $(this).val($(this).val().replace(/\D/g,));}); });轉載于:https://www.cnblogs.com/kuiyeit/p/47940…

閃電模型數學_最經典的數學模型

最經典的數學模型怎樣得到最好的女孩子的數學模型【關鍵詞】怎樣得到最好女孩子數學模型由于老天爺在你的生命中安排的異性并不是同時出現任你挑選&#xff0c;因此無論你在何時選擇結婚都是有機會成本的。人們常常希望能夠獲得一個最可愛的人作為自己的伴侶。但是&#xff0c;…

最近提交一個mysql5.7的bug,提醒自己以后注意寫SQL要規范

最近幫朋友提交一個mysql5.7的bug , oracle mysql 的大神還回復我 , 以后注意書寫sql規范 , 潛臺詞是不是不要給他們增加工作量 https://bugs.mysql.com/bug.php?id86610轉載于:https://www.cnblogs.com/kelvin19840813/p/7052983.html

openssl 學習之從證書中提取RSA公鑰N 和 E

原文鏈接: http://blog.csdn.net/kkxgx/article/details/19850509 通常數字證書包含很多信息&#xff0c;其中N和E值即我們稱為的公鑰。如何從PEM 或者DER格式的證書中提出證書呢&#xff1f;下面給出代碼實現從PEM和DER編碼的證書中提出N、E。 [cpp] view plaincopy #include …

獲得漢字字符個數

//獲得漢字字符個數function ChineseWordsCount(text:string):Integer;var i,sum,e,c,t: Integer;begin Result:0; c : 0; sum : Length(text); if Sum0 then exit; for i : 0 to sum do begin if Ord(text[i]) > 127 then begin Inc(c); end; end;…

2020湖南省技能競賽獲獎名單_2020年湖南省職業院校技能競賽學院獲獎情況通報...

由湖南省教育廳、湖南省人力資源和社會保障廳、湖南省農業農村廳等30個單位聯合舉辦的2020年湖南省職業院校技能競賽于2019年12月28日已經圓滿結束所有競賽項目&#xff0c;我院選派了190名選手參加了園林景觀設計與施工、雞新城疫抗體水平測定、集成電路開發及應用、農機維修、…

Web browser的發展演變

我們每天都在使用著瀏覽器&#xff0c;每個人使用的瀏覽器各不一樣。在這個科技飛速發展的時代&#xff0c;一個游覽器能否站住腳跟取決于使用者的數量&#xff0c;看用戶是否喜歡這個產品&#xff0c;聽取用戶們的意見來改善。 我們這個年齡的人最初用到的瀏覽器肯定是IE瀏覽器…

nodejs簡單層級結構配置文件

在NodeJS中使用配置文件&#xff0c;有幾種比較不錯的方案&#xff1a;第一種&#xff1a;文件格式使用json是毋容置疑的好方案。格式標準&#xff0c;易于理解&#xff0c;文件內容讀取到內存之后&#xff0c;使用JSON的標準分析函數即可得到配置項。第二種&#xff1a;將配置…

C++語言基礎(1)-命名空間

一個中大型軟件往往由多名程序員共同開發&#xff0c;會使用大量的變量和函數&#xff0c;當有兩個人都同時定義了一個名字相同的全局變量或函數的時候&#xff0c;若是把他們的代碼整合在一塊編譯&#xff0c;此時編譯器就會提示變量或函數重復定義&#xff0c;C為了解決這個問…

matlab 散點圖 線性回歸圖_線性回歸思路梳理

作者&#xff1a;夏雨驕陽 封面&#xff1a;自己想吧1簡單線性回歸1根據研究目的確定因變量和自變量。2判斷有無異常值。通過繪制散點圖直觀觀察&#xff1b;亦可通過線性回歸的【統計】→【個案診斷】→【所有個案】進行分析&#xff0c;若標準殘差超過[-3,3]&#xff0c;則…

物聯網云端設計分析

物聯網是世界信息產業發展的新浪潮&#xff0c;智能手表、智能手環、智能燈等物聯網產品不斷的改變著人們的生活方式。那這些產品是怎么設計出來的呢&#xff1f;其實物聯網操作系統不光由本地物聯網設備上的操作系統組成&#xff0c;還包括提供物聯網終端設備支持的云端架構。…

PHP使用文件流下載文件方法(附:解決下載文件內容亂碼問題)

記得高中時候做過游戲私服&#xff0c;那時候的游戲主頁是用PHP寫的&#xff0c;因為文件很固定&#xff0c;客戶端&#xff0c;登陸器和一些小工具&#xff0c;文件數目也不是很多&#xff0c;所以都是直接把下載鏈接寫死的&#xff0c;直接鏈接到本地服務器的文件目錄&#x…

Redis和Memcached的區別

2019獨角獸企業重金招聘Python工程師標準>>> Redis的作者Salvatore Sanfilippo曾經對這兩種基于內存的數據存儲系統進行過比較&#xff1a; Redis支持服務器端的數據操作&#xff1a;Redis相比Memcached來說&#xff0c;擁有更多的數據結構和并支持更豐富的數據操作…

hbase hmaster一會就沒了_淺析HBase

一、HBase簡介1、Apache HBase?是Hadoop數據庫&#xff0c;是一個分布式&#xff0c;可擴展的大數據存儲。2、當您需要對大數據進行隨機&#xff0c;實時讀/寫訪問時&#xff0c;請使用Apache HBase?。 該項目的目標是托管非常大的表&#xff08; 數十億的行*百萬的列 &#…