排列的逆

將排列(abcdef)應用(cdfbea),那麼它的逆爲(cdfbea)應用(abcdef)等價於(abcdef)應用(fdabec)算法

因此(cdfbea)的逆爲(fdabec)ide

算法A流程

  E1.獲取當前的替代X,X[i]表示i被X[i]代替,將m從1到n遍歷(所有遍歷,與起始點無關),設j爲任意負值.spa

  E2.獲取當前的i=X[m],若是當前X[m]<0,則X[m]取自身相反數,去E5.code

  E3.當前X[m]大於0,X[m]=j,j=-m,m=i,i=X[m].blog

  E4.i>0,則回E3;不然將X[m]=-j;io

  E5.m自增長1.若是m>n,算法結束.event

證實

  某排列的逆能夠分爲1~n個部分,每一個部分能夠看做一個環.經過遍歷,對於每一個點所在的環,要麼已經遍歷過要麼沒有遍歷過,對於沒有遍歷過的,一開始這個環上的某個節點會得到一個任意的負值(j),而後將當前的-m賦給X[X[m]],因爲是環路最終必定存在X[X[m]]=j。而這個過程當中全部-m均賦值給X[X[m]],只有最後一個-m沒有賦值,而剛好這個-m是咱們一開始遍歷這個環的某個節點的最終值,同時在這個過程當中,這個環路上其餘的節點都已經賦過值,所以對於沒有遍歷過的環上的節點只要先處理一個節點,其餘節點的值就會隨之計算出來。class

代碼實現

void PermutationInvertingA(char *SrcStr)
{
    int m,Len,i,j;
    Len=strlen(SrcStr);
    int *X=(int *)malloc((Len+1)*sizeof(int));
    for(i=0;i<Len;++i)
    {
        X[i+1]=SrcStr[i]-'a'+1;
    }
    for(m=1,j=-1;m<=Len;++m)
    {
        i=X[m];
        if(i<0)
        {
            X[m]=-i;
            continue;
        }
        if(i==m)
        {
            continue;
        }
        while(i>0)
        {
            X[m]=j;
            j=-m;
            m=i;
            i=X[m];
        }
        X[m]=-j;
    }
    for(i=1;i<=Len;++i)
    {
        printf("%d ",X[i]);
    }
    printf("\n");
    free(X);
}
View Code

 算法B流程

  E1.獲取當前的X[i],X[i]表示i要被X[i]代替,而後將全部的X[i]=-X[i],將m從1到n開始遍歷(所有遍歷,與起始點無關)cli

  E2.將m賦給jsed

  E3.i=X[j],若是i>0,將j=i,重複E3.

  E4.X[j]=X[-i],X[-i]=m

  E5.m自增長1,若是m>n算法結束

證實

  撤銷操做不一樣環之間的操做是不影響,因此咱們只須要看一個環就行,假設當前X[i](1<=i<=n)爲

  X[1]=-3,X[2]=-1,X[3]=-4,X[4]=-2(環爲1->3->4->2->1)

  具體流程就爲:

  將1指向的操做撤銷,將X[3]原值賦給X[1],X[3]=1

  獲得X[1]=-4,X[2]=-1,X[3]=1,X[4]=-2

  將2指向的操做撤銷,X[2]=-4,X[1]=2

  獲得X[1]=2,X[2]=-4,X[3]=1,X[4]=-2

  將3指向的操做撤銷,因爲當前X[3]爲正數,根據X[3]當前的值找到了X[1],由於X[3]的原值賦給了X[1],而後有找到了X[2],就有X[2]=-2,X[4]=3

  獲得X[1]=2,X[2]=-2,X[3]=1,X[4]=3

  將4指向的操做撤銷,先找X[4],而後找X[3],而後找X[1],而後找X[2],就有X[2]=-2,X[2]=4

  獲得X[1]=2,X[2]=4,X[3]=1,X[4]=3

  算法每一次是爲了撤銷當前的數指向的操做,而後逐步構造出最終的圖(排列)

代碼實現

void PermutationInvertingB(char *SrcStr)
{
    int m,Len,i,j;
    Len=strlen(SrcStr);
    int *X=(int *)malloc((Len+1)*sizeof(int));
    for(i=0;i<Len;++i)
    {
        X[i+1]=-(SrcStr[i]-'a'+1);
    }
    for(m=0;m<=Len;++m)
    {
        j=m;
        while(i=X[j],i>0)
        {
            j=i;
        }
        X[j]=X[-i];
        X[-i]=m;
    }
    for(i=1;i<=Len;++i)
    {
        printf("%d ",X[i]);
    }
    printf("\n");
    free(X);
}
View Code
相關文章
相關標籤/搜索