链表逆序总结
来源:互联网 发布: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;}
- 链表逆序总结
- 链表的逆序
- 链表逆序
- 链表逆序
- 链表逆序小结
- 逆序链表
- 链表逆序 :华硕
- 链表逆序
- 链表逆序
- 链表逆序
- 链表逆序
- 实现链表逆序
- 链表逆序
- 链表逆序
- 链表逆序
- 链表逆序
- 链表逆序
- 链表逆序
- NDK cynwin 环境变量配置
- POJ 1125 Stockbroker Grapevine Floyd储存所有最短路并求其最长路径
- java实现socket文件传输
- 前端MV*框架的意义
- i++ 和 ++i 效率的分析以及自定义类型的自增/自减运算符重载实例
- 链表逆序总结
- 著名的Holly Hack
- web.config中配置数据库连接的两种方式(<appSettings >与 <connectionStrings>)
- Windows服务调试
- java中的continue和break
- Oracle Data Guard For 12cR1介绍
- Parse Fatal Error at line 4 column 43: 已经为元素 "web-app" 指定属性 "xmlns"。
- 零食类电商如何差异化竞争
- 欧几里德算法和拓展欧几里德算法