我們假設單向鏈表的節點如下:
template <typename T>
class list_node
{
public:
list_node * next;
T data;
};
這個題目算是考察資料結構的最基礎的題目了,有兩種方法可以解此題:
方法一:
void reverse(node*& head)
{
if ( (head == 0) || (head->next == 0) ) return;// 邊界檢測
node* pNext = 0;
node* pPrev = head;// 儲存鏈表前端節點
node* pCur = head->next;// 擷取當前節點
while (pCur != 0)
{
pNext = pCur->next;// 將下一個節點儲存下來
pCur->next = pPrev;// 將當前節點的下一節點置為前節點
pPrev = pCur;// 將當前節點儲存為前一節點
pCur = pNext;// 將當前節點置為下一節點
}
}
這是一般的方法,總之就是用了幾個臨時變數,然後遍曆整個鏈表,將當前節點的下一節點置為前節點。
注釋:
鏈表反轉最好畫個圖,光看代碼對於新新手來說,確實是一個迷糊。
鏈表正常的順序是前一個節點的NEXT指向後一個節點。反轉就是要將後一個節點的next指向前一個節點,
所以pCur->next = pprev; 完成了這一個功能。但這隻是完成了兩個節點的反轉,所以對應的要將當前
節點的next儲存下來pNext = pcur->next;,用來當作下一次的當前節點PCur = Pnext;在下一次反轉中,當前節點
就變成了下一次反轉中的前節點。pPrev = pCur;
一直到當前節點為NULL,也就是全部轉化為止;
方法二:
node* reverse( node* pNode, node*& head)
{
if ( (pNode == 0) || (pNode->next == 0) ) // 遞迴跳出條件
{
head = pNode; // 將鏈表切斷,否則會形成迴環
return pNode;
}
node* temp = reserve(pNode->next, head);// 遞迴
temp->next = pNode;// 將下一節點置為當前節點,既前置節點
return pNode;// 返回當前節點
}