數據結構——鏈表(3)實現單鏈表反轉

方法一:非遞歸法

1.單鏈表反轉,可以不使用頭結點。
2.初始化階段:p=L(當前正序鏈表的第一個結點);
pHead=NULL,返回逆序反轉鏈表的頭結點;
pPrev=NULL,保存p的前一個結點,初始化爲NULL,之後隨着往後反轉,保存已反轉部分的第一個結點。
3.從正序鏈表的第一個結點開始,若當前結點p不爲空,①保存正序表中p所指向的下一個元素pNext=p->next。②判斷pNext是否爲空,若爲空,說明遍歷到最後一個元素,返回頭結點;若不爲空,執行三次更新:p->next =pPrev;(當前結點的下一個結點,是上一步保留的已反轉子表的第一個元素);pPrev=p;(再新加入反轉元素之後,更新pPrev結點);p=p->next;(更新要搜索的結點)。
這裏寫圖片描述
具體實現如下:

/*反轉鏈表*/
Linklist ListReverse(Linklist L)
{
    Linklist p,pNext;
    Linklist pPrev=NULL;
    Linklist pHead=NULL;
    p=L;
    while(p!=NULL)
    {
        pNext=p->next;
        if (pNext==NULL)
             pHead=p;
        p->next=pPrev;
        pPrev =p;
        p=pNext;

    }
    return pHead;

}


int main()
{
    Linklist L;
    InitList1(&L);          //初始化函數、插入數據函數、統計長度函數可參考前面幾篇中的例子

    int len1=ListLength1(L);
    printf("%d\n",len1);

    for (int i=1;i<=5;i++)
    {
        ListInsert1(&L,1,i);
    }
    int len2=ListLength1(L);
    printf("%d\n",len2);

    Linklist p =L;
    for(int i=1;i<=len2;i++)
    {
        printf("%d\n",p->next->data);
        p=p->next;
    }


    ListTraverse1(L);

    Linklist LReverse=ListReverse(L);
    int lenLReverse=ListLength1(LReverse);

    //反轉之後,無頭結點,直接從第一個元素輸出。
    for(int i=1;i<=lenLReverse;i++)
    {
        printf("\n%d",LReverse->data);
        LReverse=LReverse->next;
    }
    getchar();

}

擴展:
若不對鏈表做反轉,直接做逆序輸出,則使用遞歸法即可。首先找到最後一個元素,然後依次輸出。

/*正序鏈表進行逆序輸出*/
Status ListPrintReverse(Linklist L)
{
    if (L->next!=NULL)
    {
        ListPrintReverse(L->next);//遞歸調用本函數
        printf("\n%d",L->next->data);
    }
    return OK;
}

方法二:遞歸法:注意遞歸之後,返回逆序後的第一個結點指針;注意逆序後最後一個結點指向空。否則可能會造成循環。
步驟:判斷是否爲空或只有一個結點。①若是,則直接返回該頭結點。②若不是,則進入遞歸步驟,找到最後一個結點,並記錄新的頭結點。然後對最後兩個結點進行反轉。最後一個結點指向倒數第二個結點;倒數第二個結點指向空。依據此規律處理前面的結點即可。
這裏寫圖片描述

/*反轉鏈表:2.遞歸法*/
/*遞歸法要考慮:第一個結點位置、最後一個結點指向NULL*/
Linklist ListReverseRecursion(Linklist L,Linklist &head)
{
    Linklist p=L;
    Linklist pPrev=NULL;
    if(p==NULL || p->next ==NULL)
    {
        head =p;
        return p;
    }
    else
    {
        Linklist temp=ListReverseRecursion(p->next,head);
        p->next->next=p;    
        p->next=NULL;
        return temp;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章