題目:定義一個函數,輸入一個鏈表的頭結點,反轉該鏈表並輸出反轉后鏈表的頭結點。
假設有鏈表A->B->C->D->E->F->G。在反轉鏈表過程中的某一階段,其鏈表指針指向為:A<-B<-C<-D E->F->G。也就是說在結點D之前的所有結點都已經反轉,而結點D后面的結點E開始的所有結點都沒有反轉。這樣D跟E之間存在了斷裂。我們如果要實現鏈表的反轉,會有以下幾個重要步驟:
- D->E變為D->C,指針反轉
- 指針往后移動一個,操作下一個結點E
- 結合1.2我們發現需要操作3個指針,分別是C,D,E。
因此可以考慮存儲C/D/E三個結點的指針,通過這三個結點的指針實現反轉。
代碼實例:

#include<iostream> #include<stdlib.h> #include<stack> using namespace std; //鏈表結構 struct ListNode { int m_nValue; ListNode* m_pNext; }; //創建一個鏈表結點 ListNode* CreateListNode(int value) { ListNode *pNode=new ListNode(); pNode->m_nValue=value; pNode->m_pNext=NULL; return pNode; } //遍歷鏈表中的所有結點 void PrintList(ListNode* pHead) { ListNode *pNode=pHead; while(pNode!=NULL) { cout<<pNode->m_nValue<<" "; pNode=pNode->m_pNext; } cout<<endl; } //往鏈表末尾添加結點 /* 注意這里pHead是一個指向指針的指針,在主函數中一般傳遞的是引用。 因為如果要為鏈表添加結點,那么就會修改鏈表結構,所以必須傳遞引用才能夠保存修改后的結構。 */ void AddToTail(ListNode** pHead,int value) { ListNode* pNew=new ListNode();//新插入的結點 pNew->m_nValue=value; pNew->m_pNext=NULL; if(*pHead==NULL)//空鏈表 { *pHead=pNew; } else { ListNode* pNode=*pHead; while(pNode->m_pNext!=NULL) pNode=pNode->m_pNext; pNode->m_pNext=pNew; } } ListNode* ReverseList(ListNode* pHead) { ListNode* pNode=pHead;//當前結點 ListNode* pPrev=NULL;//當前結點的前一個結點 ListNode* pReversedHead=NULL;//反轉鏈表頭結點 while(pNode!=NULL) { ListNode* pNext=pNode->m_pNext; if(pNext==NULL)//如果當前結點的下一個結點為空,那么反轉鏈表的頭結點就是當前結點。 pReversedHead=pNode; pNode->m_pNext=pPrev;//當前結點指向前一個結點 pPrev=pNode;//pPrev和pNode往前移動。 pNode=pNext;//這里要使用前面保存下來的pNext,不能使用pNode->m_pNext } return pReversedHead;//返回反轉鏈表頭指針。 } void main() { //創建結點 ListNode* pNode1=CreateListNode(1);//創建一個結點 PrintList(pNode1);//打印 //往鏈表中添加新結點 AddToTail(&pNode1,2);//為鏈表添加一個結點 AddToTail(&pNode1,3);//為鏈表添加一個結點 AddToTail(&pNode1,4);//為鏈表添加一個結點 AddToTail(&pNode1,5);//為鏈表添加一個結點 AddToTail(&pNode1,6);//為鏈表添加一個結點 AddToTail(&pNode1,7);//為鏈表添加一個結點 //打印鏈表 PrintList(pNode1);//打印 //反轉鏈表 ListNode* pReversedHead=ReverseList(pNode1); PrintList(pReversedHead);//打印 system("pause"); }
運行結果:
1
1 2 3 4 5 6 7
7 6 5 4 3 2 1
ps:2012-5-3
發現有一種更加簡潔的寫法,就是不需要pReversedHead指針,從上述程序我們可以看出來pReversedHead指針只是單純的用來保存反轉鏈表的頭指針,但是pPrev和pNode指針其實就包含反轉鏈表的頭指針,因此我們沒有必要單獨定義一個頭指針來保存。修改后的函數如下所示:

ListNode* ReverseList2(ListNode* pHead) { ListNode* pNode=pHead;//當前結點 ListNode* pPrev=NULL;//當前結點的前一個結點 while(pNode!=NULL) { ListNode* pNext=pNode->m_pNext; pNode->m_pNext=pPrev;//當前結點指向前一個結點 pPrev=pNode;//pPrev和pNode往前移動。 pNode=pNext;//這里要使用前面保存下來的pNext,不能使用pNode->m_pNext } return pPrev;//返回反轉鏈表頭指針。 }