全序列算法遞歸實現——回溯

這篇博文先考慮簡單的數字的情況,如果輸入數字4,即輸出所有1-4組成的序列,

爲了熟悉回溯算法,因爲本人一直都不太熟悉回溯算法。。。所以還是特地記一下blog吧,

先上圖1:

095856365.jpg

注意到紅線的走向即爲回溯算法的走向。

上一下代碼,下面再作分析:

#include <stdio.h>
#define MAX 10
int flags[MAX];
int datas[MAX];
int n;
void print(void);
void huisu(int step);
int main(void){
    printf("Input a num < 10 :\n");
    scanf("%d",&n);
    huisu(0);
    return 0;
}
void print(){
    int i;
    for(i=0; i<n;i++){
        printf("%d ",datas[i]);
    }
    printf("\n");
}
void huisu(int step){
    int i;
    if(step==n)
        print();
    else{
        for(i=0; i<n;i++){
            if(!flags[i]){
                flags[i] = 1;
                datas[step] = i+1;
                huisu(step+1);
                flags[i] = 0;
            }
        }
    }
}

flags數組用於判斷該數字是否訪問過,如果訪問過即繼續尋找未訪問的flags,

當step==N(如題目一開始提到的N=4),即已經到達4個數字,即已經找到一個序列輸出,否則回溯

下面的圖爲代碼分析圖:

103712755.jpg

注意到步驟6爲第一次回溯,此時前面的datas[0]=1,datas[1]=2並沒有發生改變。

for循環上一次只走到i=2這個步驟。當回溯到huisu(3)時,繼續執行flags[2]=0並且繼續走for循環,i++到達i=3的位置,這時flags[3]=1訪問過,datas[2]=4,huisu(3)要求for循環再找未被訪問的flags,找到flags[2]=1,此時step爲3,datas[3]=4併到huisu(4)輸出。



作了簡單的修改,使其可以支持任意字符的全序列排序:

#include <stdio.h>
#define MAX 10
int flags[MAX];
char result[MAX];
char first[MAX];
int n;
void print(void);
void huisu(int step);
int main(void){
    int i;
    printf("Input a num < 10 :\n");
    scanf("%d",&n);
    getchar();//****獲得序列中的換行符
    for(i=0;i<n;i++)
        scanf("%c",&result[i]);//****
    for(i=0;i<n;i++)
        first[i]=result[i];//****
    huisu(0);
    return 0;
}
void print(){
    int i;
    for(i=0; i<n;i++){
        printf("%c ",result[i]);//****
    }
    printf("\n");
}
void huisu(int step){
    int i;
    if(step==n)
        print();
    else{
        for(i=0; i<n;i++){
            if(!flags[i]){
                flags[i] = 1;
                result[step] = first[i];//****first存放一開始的字符數組
                huisu(step+1);
                flags[i] = 0;
            }
        }
    }
}

帶有//****字樣的爲修改部分。由數字的全序列裏面對datas[step]=i+1進行啓發,進行1-4的排序,如果改爲datas[step]=i即爲進行0-3的排序,對應任意字符數組中的下表0-3的任意排序。記得需要注意的是result對應的爲step(每一步都對應有其result值),需要回溯的爲step+1,其餘都爲改變i

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章