一道TCL的筆試題---遞迴

qinboxiang232發表於2014-03-15

在下面這個程式片段中的劃線處填上適當的表示式,使之逆序輸出陣列元素。
--------------------------------------------------------------------------------


void recur(int a[], int k)
        {
                int tmp;
                if(_____)
                {
                        recur(_____, _____);
                        tmp = a[0];
                        a[0] = a[k-1];
                        a[k-1] = tmp;
                }
        }


--------------------------------------------------------------------------------


這道題目要用遞迴的思想完成陣列元素的逆序排列,我們先來複習一下有關遞迴函式一般解題思路。


一般而言,遞迴函式要有一個恰當的返回條件,以便到達那個條件的時候返回,不至於無窮巢狀進去,因此這個返回條件一定要在某個時候成立。另外,遞迴解決問題的思路就是:如果我要完成A任務,我必須先完成B任務,而要完成B任務,我又必須完成C任務……以此類推,就像經典的漢諾塔問題一樣,到最後只需要解決掉最簡單的那個任務即可,以此返回便能達到目的。如下圖:


回到這道題目來,如果給出一個陣列{1,2,3,4,5,6,7,8},又假設此時令k=6,即要讓前6個元素逆序,我們可以這麼分解問題:要讓1,2,3,4,5,6逆序,我可以先讓2,3,4,5逆序,只要它們逆序了,我只需交換1和6即可;而要解決這第二個問題,我可以先讓3,4逆序,只要它們逆序了,我只需交換2和5即可,最後我只需交換3和4即可。因此交換序列中的中間兩個元素成為我們用遞迴思想解決這道題的第一步。


首先我們來確定返回條件,這個好辦,只要k值大於等於2,我們才有交換的必要,否則根本不需要交換。這個應該沒啥異議的,if語句裡面填的應該就是k>1或者k>=2。


void invert_printf(int *a,int n)
{
    if(n>1)
    {
        invert_printf(a+1,n-2);
        {
            int tem;
            tem=*a;
            *a=*(a+n-1);
            *(a+n-1)=tem;
        }
    }

}
void main()
{
    int n,p[20];
    while(scanf("%d",&n)&&n)
    {
        int i;
        for(i=0;i<n;i++) scanf("%d",p+i);
        invert_printf(p,n);
        for(i=0;i<n;i++) printf("%d ",*(p+i));
        printf("\n");
    }
}




相關文章