原地排序与链表翻转

有个长度为 n 的 (key,val) 数组 a,其中 key 是 int 类型,并且其值在 [0, n) 之间(前闭后开,包括 0 不包括 n),该数组按 key 是乱序的,但没有重复 key。

题目要求:对 a 原地按 key 排序,可以使用常数个临时变量,不允许使用其它额外空间,时间复杂度必须是O(n)

我曾经写过另外一个问题:排列的分解(必须看),与此有点类似:但其实不同。

 

本质的不同在于:那个问题是对循环链表逆时针旋转1个单位,而该问题是要对循环链表顺时针旋转1个单位。逆时针旋转很容易,因为是 forward copy。但是顺时针旋转需要 backward copy,对数组(更 general 一点,是 bidirectional iterator)的 backward copy 很容易,但是对单链表的 backward copy,就比较困难了。

为了解决 backward copy 的问题,我们可以把这个循环链表先进行翻转,然后再 forward copy,思路有了,代码如下:

 

  • 如果 val 类型的拷贝代价很低(比如象上面demo中的int),可以也可以不用翻转链表,多拷贝两次即可:

在最坏情况下,这个版本对 val 的拷贝次数是上个版本的3倍,但是因为避免了翻转链表,也就减少了多一个循环的开销,这样的循环开销也许会造成大量的cpu cache 失效…… 各有利弊

作者:
该日志由 csdn-whinah 于2012年04月11日发表在算法分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
转载请注明: 原地排序与链表翻转
标签:
【上一篇】
【下一篇】

您可能感兴趣的文章:

发表评论

您必须 登录 后才能发表评论。