怎样实现链表的链表归并排序算法

> 用C语言编写的有关,两个单链表的归并排序操作.用C语言编写的有关,两个单链表的归并排序操作.已有 432903个资源相关资源下载专区上传者其他资源其它热门资源本周本月全部文档信息资源大小:592B上 传 者: () 上传日期:资源类型:应用文档资源积分:1分评
论:下载次数:0参与讨论:标&&&&签:分&&&&享:文档简介用C语言编写的有关,两个单链表的归并排序操作.文件列表.BMP----|000005.BMP----|000010.BMP----|000024.BMP----|000025.BMP----|000027.BMP----|000039.BMP----|000059.BMP----|000068.BMP----|000074.BMP----|000078.BMP----|000092.BMP----|000108.BMP----|000109.BMP----|000113.BMP----|000122.BMP----|Thumbs.db.NET Compact Framework .dep----|lcd_lib.o.d----|main.o.d----|twi_i2c.o.d.deps----|ControlResource.Po----|DCU99Editor.Po----|DuplexEditor.Po.eclipseme.tmp----|emulation----|----|PhoneBook.jad----|----|PhoneBook.jarverified----|classes----|----|com----|----|----|north----|----|----|----|phonebook----|----|----|----|----|model----|----|----|----|----|----|Account.class----|----|----|----|----|----|ApplicationException.class----|----|----|----|----|----|Index.class----|----|----|----|----|----|Model$AccountFilter.class----|----|----|----|----|----|Model$IndexFilter.class----|----|----|----|----|----|Model.class----|----|----|----|----|----|Preference.class----|----|----|----|----|----|UserModel.classui----|ConfirmationDialog.class----|DetailInfoUI.class----|Dialog.class----|DialogListener.class----|IndexFunctionUI$ListIndex.class----|IndexFunctionUI.class----|ListMerchantGroupUI.class----|ListPhoneUI.class----|LoginUI.class----|MerchantGroupDetailInfoUI.class----|NewPhoneUI.class----|SearchPhoneUI.class----|Title.class----|UIController$1.class----|UIController$EventID.class----|UIController.class----|WaitCanvas$1.class----|WaitCanvas.class----|WelcomeUI.classPhoneBookMIDlet.class.metadata----|.plugins----|----|org.eclipse.core.resources----|----|----|.projects----|----|----|----|Nios II Device Drivers----|----|----|----|----|.location----|----|----|----|----|.propertieshello_led_0----|.markers----|.propertieshello_led_0_syslib----|.markers----|.properties.root----|112.tree.safetable----|org.eclipse.core.resourcesorg.eclipse.core.runtime----|.settings----|----|org.eclipse.cdt.core.prefs----|----|org.eclipse.cdt.ui.prefs----|----|org.eclipse.ui.prefsorg.eclipse.ui.workbench----|dialog_settings.xml----|workbench.xml.bak_0.log.bak_1.log.bak_2.log.bak_3.log.lock.logversion.ini.myeclipse----|CVS----|----|Repository----|----|Root.netkuangjia.settings----|CVS----|----|Entries----|----|Repository----|----|Rootorg.eclipse.core.resources.prefs.sopc_builder----|install.ptf.svn----|prop-basepropstext-base----|readme.txt.svn-basetmp----|prop-basepropstext-baseall-wcpropsdir-prop-baseentriesformat.tmp_versions----|dw4002.mod. Online calibration of Nyquist-rate analog-to-digital converters.pdf..dir.dat.DS_Store.NET Compact Framework mpact Framework ._.DS_Store._CotEditor_346._INSTALL._MacOS_Setup._PortVaR.actionScriptProperties.advancedproject.apriori_config.apusicproject.ccsproject.classpath.config.o.flags.cproject.cvsignore.cxl.depend.dw4002.ko.cmd.dw4002.mod.o.cmd.dw4002.o.cmd.dwg.epautoconf.o.flags.exe.file_storage.o.flags.flexProperties.gitignore.htaccess.indent.pro.lso.message.pdf.project.qmake.internal.cache.reg文件全攻略.txt.screenrc.synopsys_dc.setup.synopsys_pt.setup.untf.usbstring.o.flags.vimrc.xhdl3.xrefWW1.C相关帖子大学堂最新课程请选择理由 辱骂 色情 广告提交若举报审核通过,可奖励2下载分举报人:被举报人:baidu_linker举报的资源分:1* 类型:请选择类型资源无法下载资源分类不正确资源无法使用标题与实际内容不符含有危害国家安全内容含有反动色情等内容含广告内容版权问题,侵犯个人或公司的版权其他* 详细原因:回到顶部EEWORLD下载中心所有资源均来自网友分享,如有侵权,请发送举报邮件到客服邮箱service(.cn 或通过站内短信息或QQ:联系管理员okhxyyo,我们会尽快处理。LeetCode Sort List(单链表归并排序)
LeetCode Sort List(单链表归并排序)
LeetCode-Algorithms
题意:给出一个单链表,将其排序,要求时间复杂度O(nlgn)
思路:用归并排序,取链表的一半,在取一半时,不用先计算总结点个数,一个每次走两步,一个每次走一步,当走的快的结束是,慢的已经到总结点的一半了
代码如下:
class Solution
private ListNode mergeListNode(ListNode l1, ListNode l2)
if (null == l1) return l2;
else if (null == l2) return l1;
ListNode p1 = l1, p2 = l2;
ListNode ans = null, tail =
while (l1 != null && l2 != null)
if (l1.val & l2.val)
if (tail == null)
ans = tail = l1;
tail.next = l1;
tail = tail.
if (null == tail)
ans = tail = l2;
tail.next = l2;
tail = tail.
if (l1 != null) tail.next = l1;
else if (l2 != null) tail.next = l2;
public ListNode sortList(ListNode head)
if (null == head || null == head.next)
ListNode fast = head.next, slow =
while (fast != null && fast.next != null)
fast = fast.next.
slow = slow.
ListNode p = slow.
slow.next =
return mergeListNode(sortList(head), sortList(p));
我的热门文章
即使是一小步也想与你分享@Author: 张海拔
@Link:&/zhanghaiba/p/3534521.html
链表不像数组通过计算来随机存取,高效的排序算法如快速排序、堆排序都比较难实现,而归并排序就适合给链表排序。
在"有序单链表的合并&"问题中,我对带头结点和不带头结点的 有序单链表的合并算法做了比较全面的介绍。
知道了 链表的就地合并算法 比数组的合并算法时间效率要好一些,而空间复杂度则完胜,是O(1)(不然怎么叫就地)。
我们已经熟悉数组的&归并排序&&&,链表的归并排序用到的归并算法肯定是一样的,是典型的分治(二分)过程。
还是先给出伪代码:
merge_sort()
if 元素只有一个(已经有序)
划分为左右两段
对左段进行merge_sort()
对右段进行merge_sort()
//此时左段和右端已经有序
对左段和右段进行sorted_merge()
sorted_list_merge()我们已经实现过了,merge_sort的思路也清晰了,剩下的问题是,怎样把一段链表划分为两段?
链表的追及问题其实挺经典的,比如&链表是否有环&和&确定链表倒数第K个元素&,这样的问题都是用到追击(相对速度)的思路。
这里也一样,使用一个slow指针和一个fast指针,让fast指针相对slow指针的移动速度是单位1。这样fast走到尽头时,slow就在&中间&位置了。
这个时候需要考虑一些边界问题。
只有一个元素时,merge_sort()直接返回(已经有序,不用再处理),不再划分。
那么只有两个元素的情况对应划分的最小子问题&&
首先,直接让slow初始指向first,而fast初始指向first-&next,
然后每次前进让fast先后一步再验证是否到边界,若没有则fast和slow都走一步。
这样初始化后,fast走一步后发现到了边界,slow便不走,还是指向first。
将左段链表的首节点指针left = first,右段链表的首节点指针right = slow-&next,然后切断原链表,即slow-&next = NULL;
对于最小子问题这样划分是正确的(left指向第一个节点,right指向第二个节点)。
由于fast相对slow速度为1,且最小子问题也正确,对于更大的子问题,不管划分边界是[n/2]取上界还是下界问题都不大。
所以,这个算法时间复杂度仍然是O(n*lgn),空间复杂度O(1)
数组的归并排序合并过程需要来回两次循环复制即2*O(n),而链表的归并排序是划分过程仅需要循环一次1*O(n)。
两者递归的深度是一样的(都是二分)。
综合来看,链表归并排序的时间复杂度系数应该更低,即理论上会比数组归并排序更快。
下面给出链表归并排序的完整实现&&
sorted_list_merge_in_place()是递归实现的
sorted_list_mrege_in_place2()是迭代实现的
list_merge_sort()接受带头结点的单链表,返回也是带头结点的单链表
list_merge_sort_core()接受不带头结点的单链表,返回的也是不带头结点的单链表
通过简单包装一下list_merge_sort_core(),即可实现list_merge_sort()
默认支持带头结点的单链表是考虑到问题集的其它链表都是带头结点的,而不带头结点适用性更强,实现了后者,前者只需简单包装就能实现。
约定:带头结点的单链表的头结点指针命名为head,不带头结点的单链表的第一个(首)结点的指针命名为first。带头结点的单链表的第一个有效元素的指针也叫first。
*Author: ZhangHaiba
*File: merge_sort_for_singly_linked_list.c
*a demo shows merge sort for singly_linked_list
9 #include &stdio.h&
10 #include &stdlib.h&
11 #define INF 0x7fffffff
13 typedef struct node *
14 typedef struct node {
19 //public
*recieve a singly linked list with Head Node and
*return a singly linked list with Head Node as well
24 link list_merge_sort(link list_head);
25 link NODE(int item, link next);
26 link list_create(int n);
27 void list_travel(link head);
28 void list_destroy(link head);
30 //private
31 /*recieve a singly linked list without Head Node and
*return a singly linked list without Head Node as well
34 link list_merge_sort_core(link list_first);
35 void list_divide(link src_list, link *left_list, link *right_list);
36 link sorted_list_merge_in_place(link src_list_a, link src_list_b);
//recusive
37 link sorted_list_merge_in_place2(link src_list_a, link src_list_b); //iterative
40 int main(void)
scanf("%d", &n);
link list_a = list_create(n);
printf("before merge sort, travel:\n");
list_travel(list_a);
list_a = list_merge_sort(list_a);
printf("after merge sort, travel:\n");
list_travel(list_a);
list_destroy(list_a);
55 link list_merge_sort(link head)
if (head == NULL) //if [list with Head Node] have not Head Node
return NULL;
return NODE( INF, list_merge_sort_core(head-&next) );
62 link list_merge_sort_core(link first) //first node pointer
link left,
if (first == NULL || first-&next == NULL)
list_divide(first, &left, &right);
left = list_merge_sort_core(left);
right = list_merge_sort_core(right);
return sorted_list_merge_in_place2(left, right);
74 //guarantee first != NULL
75 void list_divide(link first, link *left, link *right)
link slow = first, fast = first-&
while (fast != NULL) {
fast = fast-&
if (fast != NULL) {
fast = fast-&
slow = slow-&
*right = slow-&
slow-&next = NULL;
91 link sorted_list_merge_in_place(link left, link right)
if (left == NULL)
if (right == NULL)
link first = NULL;
if (left-&item &= right-&item) {
first-&next = sorted_list_merge_in_place(left-&next, right);
first-&next = sorted_list_merge_in_place(left, right-&next);
108 link sorted_list_merge_in_place2(link left, link right)
link tmp_head = NODE(INF, NULL);
link first = tmp_
for (; left != NULL && right != NULL; first = first-&next) {
if (left-&item &= right-&item)
first-&next = left, left = left-&
first-&next = right, right = right-&
first-&next = left != NULL ? left :
first = tmp_head-&
free(tmp_head);
126 link NODE(int item, link next)
link born = malloc(sizeof (node));
born-&item =
born-&next =
134 //tail insert
135 link list_create(int n)
link head = NODE(INF, NULL);
link tail =
for (i = 0; i & ++i) {
scanf("%d", &item);
tail-&next = NODE(item, NULL);
tail = tail-&
149 void list_travel(link head)
for (head = head-& head != NULL; head = head-&next)
printf(head-&next == NULL ? "%d\n" : "%d ", head-&item);
155 void list_destroy(link head)
head-&next == NULL ? free(head) : list_destroy(head-&next);
测试示范:
ZhangHaiba-MacBook-Pro:code apple$ ./a.out
before merge sort, travel:
after merge sort, travel:
ZhangHaiba-MacBook-Pro:code apple$ ./a.out
4324 31 515 41 46 43 8 53 3
before merge sort, travel:
4324 31 515 41 46 43 8 53 3
after merge sort, travel:
3 8 31 41 43 46 53 515 4324
阅读(...) 评论()

我要回帖

更多关于 单链表归并排序 的文章

 

随机推荐