0基礎算法基礎學算法 第六彈 遞歸

  最近呢也是有好久沒有更新博客了,主要是由於平時比較忙,畢竟等疫情完全解封qj我也要小升初考試了,因此打算趕在今天更新點乾貨。ios

  在各大oi賽事上,遞歸和遞推算是個基礎而重要的算法,遞歸在熟練運用後能夠實現dfs,dfs是深度優先搜索,之後會講到關於dfs的;而遞推是一種用若干步可重複運算來描述複雜問題的方法,好比斐波那契數列,上樓梯等都是能夠經過遞推來進行實現的,而下一講即將會具體講述遞推,今天的主題是遞歸 c++

如今切入正題算法

一.遞歸框架

  遞歸函數其實在比賽中特別常見,不少人在比賽的時候遇到不會的題就直接打暴力,可是若是你會遞歸的話,你能夠用一通pmn或者dfs直接爆搜(據有關人士稱,去年提升組若是pmn能夠的200+。。。)那到底什麼是遞歸呢?遞歸函數,便是本身調用本身,理解遞歸最好是經過一個例子來理解,好比,超經典的基礎題,1+2+3+4+...+n-2+n-1+n=?遇到這個題,通常作法是利用for循環一個一個的累加,提供一個c++代碼函數

#include<bits/stdc++.h>//萬能頭文件,建議比賽時使用
using namespace std;
int s,i,n;
int main()
{
    S=0;
  cin>>n;
for(i=1;i<=n;i++) s=s+i; cout<<s; return 0; }

這是最簡單也最直觀的代碼,若是使用遞歸實現雖然會看起來麻煩一點,但對遞歸的理解有好處。算法的流程圖大概是是這樣的過程有點相似於倒着的for法,結合代碼咱們一塊兒看看,運行結果是同樣的網站

#include <iostream>
using namespace std;
int dg(int n) //遞歸函數,n定義的是局部變量不衝突 
{
    if(n==1) return 1;
    return (dg(n-1)+n);//進行遞歸 
}
int main() {
    int n;
    cin>>n;
    cout<<dg(n); 
    return 0;
}

大概就是這樣子的,遞歸的一個基本的主體框架有兩個部分,一個是反覆遞歸的過程,還有就是停止條件,否則你的程序停不下來可很悲催的一件事,相信我,程序死活不輸出你也找不到問題所在,只能瀏覽程序了,到了後期,這些細節要愈加的注意,由於如今我寫代碼都動不動65+行,好比高精度就要佔你數十行;spa

#include <iostream>
using namespace std;
int dg(int n) //遞歸函數,n定義的是局部變量不衝突 
{
    if(終止條件) return 停止的返回值;
    dg(n-1);//進行遞歸 (舉例)
    //遞歸的形式須要根據須要而調整,好比有時候你也許會是是dg(n+1)+n; 
}
int main() {
    dg(n); //調用遞歸函數 
    return 0;
}

遞歸的基本模板👆;code

重點是本身調用本身這一塊比較難理解,能夠本身試圖去嘗試寫一些遞歸程序blog

這裏再和你們分享一道經典的題:排序

  設有n個數已經按從大到小的順序排列,如今輸入x,判斷它是否在這n個數中,若是存在則輸出yes,不然輸出 no;                                           

  拿到題目先分析(這裏節省點位置,流程圖留給大家本身去畫吧🙂),這是一道比較簡單的數據查找的問題,通常使用順序查找,使用for循環,這個for循環也能夠「遞歸化」;分別展現一下for作法和遞歸作法(其實還有一個作法會在將來講二分查找的時候講)

#include <bits/stdc++.h>//萬能頭能夠省好多事 
using namespace std;
int main(){
    int a[10];//用於錄入10個數 
    int n; 
    for(int i=0;i<10;i++) cin>>a[i];
    sort(a,a+10); //快速排序函數庫,加了萬能頭就不用加它的頭文件了
    cin>>n;
    for(int i;i<10;i++) 
    {
        if(a[i]=n)
        {
            cout<<"yes";
            return 0;    
        }
    }
    cout<<"no";
    return 0;
} 
#include <bits/stdc++.h>//萬能頭能夠省好多事 
using namespace std;
int a[10];//用於錄入10個數
bool b=false;
void fun(int n,int k)
{
    if(n==a[k])
    {
        b=true;
        return;
    }//找到了,標記一下,直接跳出,不須要再找了 
    else if(k<0) return; //所有找完都沒找到,也不用找了 
    fun(n,k-1);//調用部分 
 } 
int main(){
    int n; 
    for(int i=0;i<10;i++) cin>>a[i];
    sort(a,a+10); //快速排序函數庫,加了萬能頭就不用加它的頭文件了
    cin>>n;
    int k=9;//下標從0開始 
    fun(n,k);
    if(b) cout<<"yes";
    else cout<<"no";
    return 0;
} 

註釋 上:for遍歷法 遞歸遍歷法 敬請期待二分查找(還不快關注。。。)

上面的作法都是可行的,運行結果一切正常

 博客留題!:

  洛谷遞歸題單 https://www.luogu.com.cn/training/109#problems

  酌量練習,把握分度,否則會沉迷於洛谷這個花花綠綠的遊戲網站 (劃去)

  今天的內容就是這些了,下次會講遞推,還會分享一些資料,假如你有興趣,先點贊👍,關注➕走一波,關注後歡迎白嫖😀;

相關文章
相關標籤/搜索