1. 程式人生 > >單鏈表反轉(三種方法總結)

單鏈表反轉(三種方法總結)

題目:輸入一個連結串列,反轉連結串列後,輸出連結串列的所有元素。

方法一:

思路:從原連結串列的頭部一個一個取節點並插入到新連結串列的頭部

(1)

struct ListNode{
        int val;
        struct ListNode *next;
        ListNode(int x):val(x),next(NULL){}
};

class Solution{
public:
        ListNode* ReverseList(ListNode*pHead){
                ListNode* newh=NULL;
                for(ListNode* p=pHead;p;)
                  {
                         ListNode* tmp=p->next;
                         p->next=newh;
                         newh=p;
                         p=tmp;
                  }
                 return newh;
}
};
(2)
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == NULL)
            return pHead;      
        ListNode *res,*cur,*next;
        res = new ListNode(-1);
        cur = pHead;
        next = cur->next;
        while(cur != NULL)
            {       
            ListNode *first = res->next;
            cur->next = first;
            res->next = cur;

            cur = next;
            next = next->next;       
        }   
        return res->next;  
    }
};
方法二:

思路:每次都將原第一個結點之後的那個結點放在新的表頭後面。 
比如1,2,3,4,5 
第一次:把第一個結點1後邊的結點2放到新表頭後面,變成2,1,3,4,5 
第二次:把第一個結點1後邊的結點3放到新表頭後面,變成3,2,1,4,5 
…… 
直到: 第一個結點1,後邊沒有結點為止。 
程式碼如下:

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == NULL)
            return pHead;

        ListNode *res,*first,*temp;
        res = new ListNode(-1);
        res->next = pHead;

        first = res->next;       //first 始終為第一個結點,不斷後移
        while(first->next!=NULL) //temp為待前差的
            {
            temp = first->next;
            first->next = temp->next;
            temp->next = res->next;
            res->next = temp;          
        }

        return res->next;
    }
};
方法三

第三種方法跟第二種方法差不多,第二種方法是將後面的結點向前移動到頭結點的後面,第三種方法是將前面的結點移動到原來的最後一個結點的後面,思路跟第二種方法差不多,就不貼程式碼了。