Sort List[leetcode] 由归并排序的递归和循环,到本题的两种解法
来源:互联网 发布:橘子说淘宝装修工具箱 编辑:程序博客网 时间:2024/05/25 01:36
归并排序可以有两种思路----top-down 和 bottom-up
top-down:
递归实现,将数组分成两半,分别处理;再合并。
伪代码如下:
split ( A[], l, r){if ( r - l < 2) return;m = (r + l) / 2;split ( A, l, m); //split A[l…m-1]split ( A, m, r); //split A[m…r-1]merge ( A, l, m, e); //merge A[l…m-1] and A[m…e-1]}
bottom-up:
循环实现,将数组看做n个长度为1的组数组。
用width控制每次merge的子数组长度,width每次翻倍
伪代码如下:
sort ( A[], n){for (width = 1; width < n; width *= 2){for (i = 0; i < n; i += 2 * width){merge(A, i, min(i + width, n), min(i + 2 * width, n));}}}
Sort list中使用链表,不能在O(1)的时间内访问任意节点,同时注意要处理尾部节点的next,置为NULL
和上面的伪代码类似,首先实现merge函数:
ListNode * merge(ListNode * h1, int s1, ListNode * h2, int s2) { if (h2 == NULL) return h1; ListNode * h; if (h1->val < h2->val) h = advance(h1, s1); else h = advance(h2, s2); ListNode * cur = h; while (s1 && s2) { if (h1->val < h2->val) cur->next = advance(h1, s1); else cur->next = advance(h2, s2); cur = cur->next; } if (s1) { cur->next = h1; while(s1) advance(h1, s1); } if (s2) { cur->next = h2; while(s2) advance(h2, s2); } return h; } ListNode * advance(ListNode * (& n), int & size) { ListNode * temp = n; if (size == 1) n->next = NULL; n = n->next; size--; return temp; }
同时实现工具函数,访问任意位置节点
ListNode * getNode(ListNode * head, int len) { while (len -- && head) head = head->next; return head; }
循环版本主函数如下:
ListNode *sortList(ListNode *head) { ListNode * cur = head; int size = 0; while (cur) { size ++; cur = cur->next; } ListNode * pre; for (int w = 1; w <= size; w *= 2) { cur = head; for (int i = 0; i < size; i+= w*2) { ListNode * h1 = cur, * h2 = getNode(cur, w), * next = getNode(cur, 2 * w); cur = merge(h1, min(w, size - i), h2, min(w, size - i - w)); if (i == 0) head = cur; else pre->next = cur; pre = getNode(cur, min(2 * w, size - i) - 1); cur = next; } } return head; }
递归版本主函数如下:
ListNode *sortList(ListNode *head) { ListNode * cur = head; int size = 0; while (cur) { size ++; cur = cur->next; } return sort(head, size - size / 2, getNode(head, size - size / 2), size / 2); } ListNode * sort(ListNode * h1, int s1, ListNode * h2, int s2) { if (s1 == 0) return h2; if (s2 == 0) return h1; h1 = sort(h1, s1 - s1 / 2, getNode(h1, s1 - s1 / 2), s1 / 2); h2 = sort(h2, s2 - s2 / 2, getNode(h2, s2 - s2 / 2), s2 / 2); return merge(h1, s1, h2, s2); }
0 0
- Sort List[leetcode] 由归并排序的递归和循环,到本题的两种解法
- 【LeetCode】 sort list 单链表的归并排序
- list容器的特殊sort()算法:非递归--归并排序
- leetcode:Sort List(链表的归并排序)
- LeetCode Sort List 链表的归并排序
- leetcode:Sort List 使用归并排序的解决思路
- sort list leetcode (归并排序)
- 两种归并排序算法的实现:二路归并排序和基本归并排序(虚拟消除递归的二路归并排序)
- merge two sort list-leetcode 有序链表合并的二级指针简洁非递归解法
- LeetCode 22:Generate Parentheses的递归,回溯两种解法
- STL源码——list sort:归并排序的非递归实现
- LeetCode 147. Insertion Sort List插入排序链表的高效简单解法
- Leetcode Sort List 链表归并排序
- Leetcode:Sort List 对单链表归并排序
- 【leetcode 单链表归并排序】Sort List
- [leetcode] 134 Sort List (链表 & 归并排序)
- LeetCode Sort List(单链表归并排序)
- 将List转成树的两种方式(递归、循环)
- 算法导论第八章伪码转C++_计数排序
- dfhdf
- XDCTF coding200
- Android NDK开发入门
- 初步了解C++命名空间(加了继承)
- Sort List[leetcode] 由归并排序的递归和循环,到本题的两种解法
- 嵌入式 修改u-boot与Linux调试串口以及文件系统显示终端串口
- 算法导论第八章伪码转C++ __桶排序
- [2-SAT] poj 3678 Katu Puzzle
- EM 算法复述
- mysql在渗透中的技巧总结
- css基础认识一
- c语言实现面向对象编程
- zoj 3641 Information Sharing(set+并查集)