链表逆序总结

来源:互联网 发布:tvart怎么样 知乎 编辑:程序博客网 时间:2024/06/06 07:22

所谓链表逆序,是把诸如 1->2->3->4->null 的链表变换为 4->3->2-1->null。假设链表节点定义如下:

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

新建临时节点tmp_head,遍历原始链表,将原始链表头插入tmp_head之后,最后返回tmp_head。如是则返回了逆序后的链表。

ListNode * reverseList(ListNode *head){    if (head == NULL || head->next == NULL)        return head;         ListNode *tmp_head, *next;    tmp_head = new ListNode(-1);    //create a temporary head Node, notice that tmp_head->next is NULL    next = head->next;    while (head != NULL){        next = head->next;        head->next = tmp_head->next;        tmp_head->next = head;        head = next;    }    head = tmp_head->next;    delete tmp_head;                //free the temporary head Node    return head;       }

解法二:

利用三个指针p、q、n,三个指针初试时如下图所示:

然后变换指针:

然后将p、q、n向后挪动一个位置:

如是反复,直到n的值为空,此时链表如下图所示:

程序代码如下:

ListNode * reverseList(ListNode *head){    if (head == NULL || head->next == NULL)        return head;         ListNode *p, *q, *n;    p = head, q = p->next, n = q->next;    p->next = NULL;//notice that initially we should set the next filed of the first node to NULL    while (n != NULL) {        q->next = p;        p = q; q = n;        n = n->next;    }    q->next = p;        head = q;    return head;       }


接下来是两种递归实现。但链表的处理不宜使用递归,因为当链表过长的时候,容易导致栈溢出。

解法三:

ListNode * recursiveReverseList(ListNode *p, ListNode *last){    if (p->next == NULL){        p->next = last;        return p;    }        ListNode *tmp = p->next;    p->next = last;    return recursiveReverseList(tmp, p);}ListNode * reverseList(ListNode *head){    if (head == NULL || head->next == NULL)        return head;            return recursiveReverseList(head, NULL);       }

解法四:

ListNode * recursiveReverseList(ListNode *p){    if (p->next == NULL)        return p;    ListNode *new_head = recursiveReverseList(p->next);    p->next->next = p;    return new_head;}ListNode * reverseList(ListNode *head){    if (head == NULL || head->next == NULL)        return head;    ListNode *new_head = recursiveReverseList(head);    head->next = NULL;    return new_head;       }

由上可见,解法三和解法四并没有本质的不同。但相对而言,无论是函数递归调用还是代码结构,解法三更好一些。下述代码是我测试以上函数时用到的代码。建议通过如下命令编译程序:

g++ filename.cpp -std=c++11

ListNode * reverseList(ListNode *head){    return NULL;}ListNode * genList(){    vector<int> data = {1, 2, 3, 4};    ListNode * head, *tmp;    head = tmp = new ListNode(0);    for (int j = 0; j < data.size(); ++j){            tmp->next = new ListNode(data[j]);            tmp = tmp->next;    }    tmp->next = NULL;    tmp = head->next;    delete head;    return tmp;}void print_list(ListNode *head){    cout << "print_list :" << endl;    if (head == NULL){        cout << endl;        return;    }    ListNode *tmp = head;    while(tmp != NULL){        cout << tmp->val << " ";        tmp = tmp->next;    }    cout << endl;}int main(){    ListNode * head = genList();    print_list(head);    head = reverseList(head);    print_list(head);    head = reverseList(head);    print_list(head);        return 0;} 

原创粉丝点击