當前位置: 首頁>>算法&結構>>正文


深度優先搜索的遞歸實現思路及實例源碼(C++)

摘要:本文簡要介紹了深度優先搜索的遞歸實現思路給出了幾個實例的源碼

關鍵字:深度優先,遞歸,組合,整數劃分,連續整數和

遞歸深度優先的核心思想是對於當前節點(設深度為K),如果該節點合乎結題要求,就遍曆當前節點所有可

擴展節點並遞歸調用搜索方法(進入K+1深度)。算法的基本框架如下:

1.定義數組int x[N],用於記錄可用節點的索引,其中N為解空間的長度。

2.定義判斷節點是否滿足條件的函數

3.定義搜索函數


bool canuse(int k)
{
    if(x[k]滿足條件)return true;
    return false;
}
void search(int k)
{
    if(滿足條件(例如k到達某一深度)) 輸出結果;
    for(int i = 1 to n)//遍曆每一個可能的擴展節點
    {
        x[k] = i;
        if(canuse(k)) search(k + 1);

    } 
}

下麵給出兩個使用上麵思想的解決問題的實例

/*
 * 在N個數種選M個數的組合
 * Compiler: VC++ 6.0
 */
#include 

using namespace std;

#define N 9
#define M 5

int array[N]={1,2,3,4,5,6,7,8,9};

int x[N];
bool canuse(int k)
{
    if(k == 0 || k > 0 && x[k] > x[k - 1])
    {
        return true;
    }
    return false;
}

void print()
{
    for(int i = 0; i < M; ++i)
    {
        cout << array[x[i]] << " ";
    }
    cout << endl;
}

void search(int k)
{
    if(k == M)
        print();
    for(int i = 0; i < N; ++i)
    {
        x[k] = i;
        if(canuse(k)) search(k + 1);
    }

}


int main(int argc, char* *argv)
{
    search(0);
    system("pause");
    return 0;
}

/*
 * 采用遞歸實現的深度搜索算法
 * 編譯器: VC++ 6.0
 */

//例一:整數劃分
/* 問題描述,如下所示:
   5=5
   5=4+1
   5=3+3
   5=3+2
   5=3+1+1
   5=2+2+1
   5=2+1+1+1
   5=1+1+1+1+1
   一個整數可以表示為其他整數的和,
   要求使用程序輸出所有這樣的組合
   */
#include 
using namespace std;

#define N 100

int x[N];

void print_result(int k)
{
    cout << "=" << x[0];
    for(int i = 1; i < k; ++i)
        cout << "+" << x[i];
    cout << endl;
}

bool canuse(int depth)
{
    if(depth == 0 || x[depth] <= x[depth -1])
    {
        return true;
    }
    return false;
}

void search(int remainder, int depth)
{
    if(remainder == 0) print_result(depth);
    for(int num_try = remainder; num_try > 0; --num_try)
    {
        x[depth] = num_try;
        if(canuse(depth))
            search(remainder - num_try, depth + 1);
    }
}

int main(int argc, char* *argv)
{
    int n;
    while(cin>>n && n > 0 && n < N)
    {
        search(n, 0);
    }
    return 0;
}

/*
 * 將一個整數表示為連續自然數之和
 * 1+2=3
 * 4+5=9
 * 2+3+4=9
 */

#include 

using namespace std;

#define N 1000
int a[N];
bool canuse(int depth)
{
    if(depth == 0 || a[depth] == a[depth - 1] + 1)
        return true;
    return false;
}

void print(int depth)
{
    for(int i = 0; i < depth; ++i)
        cout << a[i] <<" ";
    cout << endl << endl;
}

void search(__int64 reminder, int depth)
{
    if(reminder == 0 && depth > 1) print(depth);
    for(__int64 i = reminder; i > 0; i--)
    {
        a[depth] = i;
        if(canuse(depth))
            search(reminder - i, depth + 1);
    }
}
本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/173.html,未經允許,請勿轉載。