Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 对单个链接列表排序_Algorithm_Sorting - Fatal编程技术网

Algorithm 对单个链接列表排序

Algorithm 对单个链接列表排序,algorithm,sorting,Algorithm,Sorting,如何对单个链接列表进行排序。 (这里的问题是单一属性+使用LinkedList进行排序比数组更难) 我想看看伪代码 尽量使它在时间和空间上都尽可能有效 谢谢 插入排序和快速排序都可以在单个链表上进行,其效率与在数组上相同。由于链表只是由其他项指向的多个项组成,所以您可以构造一个具有O(n)时间和O(n)空间的指针数组,使用任何具有O(n)空间的优秀排序算法进行排序(n logn)时间和O(1)空间,然后用O(n)时间和O(1)空间从头开始重建链表 总的来说,这就是O(n log n)时间和O(n

如何对单个链接列表进行排序。 (这里的问题是单一属性+使用LinkedList进行排序比数组更难) 我想看看伪代码

尽量使它在时间和空间上都尽可能有效


谢谢

插入排序和快速排序都可以在单个链表上进行,其效率与在数组上相同。

由于链表只是由其他项指向的多个项组成,所以您可以构造一个具有O(n)时间和O(n)空间的指针数组,使用任何具有O(n)空间的优秀排序算法进行排序(n logn)时间和O(1)空间,然后用O(n)时间和O(1)空间从头开始重建链表


总的来说,这就是O(n log n)时间和O(n)空间。

我相信通过就地快速排序可以做到这一点。
我错了。这对单链接列表不起作用,因为in需要能够在列表中后退。

因此,真正的问题是如何进行就地快速排序

我们走吧

1) 将指针指向链表的第一个、第二个和最后一个术语。
2) 用第二个指针在列表中单步移动,直到找到比第一个词大的词。
3) 在列表中向后移动第三个指针,直到找到一个小于第一个的项此步骤不适用于单链接列表。
4) 交换第二个和第三个指针的值。
5) 重复步骤2)到5),直到第二个指针和第三个指针相等。
6) 在第二个指针后插入第一个项

-此时,链接列表分为:
[小于x的条款]x[大于x的条款]

7) 对[terms小于x]和[terms大于x]重复步骤2)到7),直到[terms_______;小于x]块的大小为一

空间:每层3个指针。
O(对数(n))

时间:与快速排序相同
O(n log(n))通常
O(n*n)在最坏的情况下(如果列表已经排序或顺序相反)



为格式化和愚蠢而编辑

我一直在思考这个问题,我认为使用合并排序可以实现O(n log(n))时间和O(1)空间条件

让我们看看……
以列表为例:
3->2->1->5->6->4

第一关:
为第一个、第二个和第三个术语设置指针
将第一个指针和第二个指针之间的较小项设置为指向较大项。
将两个术语中的最后一个术语设置为指向原始列表的其余部分。
重复此操作直到列表结束。
2->3->1->5->4->6

此时,每对术语都是有序的

第n遍:
设置指向第1个、(2^(N-1))项和第(2^(N))项+1项的指针
取值较小的节点并增加其指针。
重复此过程,直到两个列表(长度为2^N)都用尽,每次都将较小值的节点追加到前一个较小值的节点。
将指针设置为原始列表的其余部分。
重复此操作,直到列表结束

第0次通过:3->2->1->5->6->4(1个术语的每个区块都是有序的)(平凡的)
第一次通过:2->3->1->5->4->6(每一块2个术语都被订购)
第二遍:1->2->3->5->4->6(每一块4个术语都被订购)
第三遍:1->2->3->4->5->6(每一块8个术语都已排序)

时间:记录(n)个过程,每个过程有n个比较。
O(n对数(n))

空格:指针和整数变量

O(1)

合并排序只涉及几个简单的步骤:

  • 检查列表是否为空或是否有单个元素。如果是,请原封不动地返回列表

  • 把名单一分为二。合并两部分

  • 通过重复从两个列表中取出较小的元素来合并列表。由于零件列表已经排序,这只是查看两个列表中的第一个元素并选择较小的元素的问题

  • 返回合并列表

  • 结果,您将得到一个按最小元素的顺序排序的链表

    Haskell中的代码示例:

    import Data.List(splitAt)
    
    --Mergesorts a list by smallest element first.
    sort :: Ord a => [a] -> [a]
    sort = sortBy (<)
    
    --Generic sort that can sort in any order.
    sortBy :: (a -> a -> Bool) -> [a] -> [a]
    sortBy _ [] = []
    sortBy _ [x] = [x]
    sortBy f xs = merge f (sortBy f first) (sortBy f second)
        where
            (first,second) = split xs
    
    --Splits a list in half.
    split :: [a] -> ([a],[a])
    split xs = splitAt (halfLength xs) xs
    
    --Returns a lists length divided by two as a whole number (rounded).
    halfLength :: [a] -> Int
    halfLength = round . (/2) . fromIntegral . length
    
    --Merges two lists in the provided order.
    merge :: (a -> a -> Bool) -> [a] -> [a] -> [a]
    merge _ [] [] = []
    merge _ [] (y:ys) = y:ys
    merge _ (x:xs) [] = x:xs
    merge f (x:xs) (y:ys) =
        if f x y
            then x : merge f xs (y:ys)
            else y : merge f (x:xs) ys
    
    导入数据列表(splitAt)
    --merge首先按最小元素对列表排序。
    排序::Ord a=>[a]->[a]
    排序=排序方式(a->Bool)->[a]->[a]
    sortBy[]=[]
    排序比ux]=[x]
    sortBy f xs=合并f(sortBy f first)(sortBy f second)
    哪里
    (第一,第二)=拆分X
    --将列表一分为二。
    拆分::[a]->([a],[a])
    拆分xs=拆分(半长xs)xs
    --返回列表长度除以2的整数(四舍五入)。
    半长度::[a]->Int
    半长=圆形。(/2) . 从积分。长度
    --按提供的顺序合并两个列表。
    合并::(a->a->Bool)->[a]->[a]->[a]->[a]
    合并[][]=[]
    合并[](y:ys)=y:ys
    合并ux(x:xs)[]=x:xs
    合并f(x:xs)(y:ys)=
    如果f×y
    然后x:merge f xs(y:ys)
    else y:merge f(x:xs)ys
    
    家庭作业?如果是这样的话,请说明你到目前为止已经走了多远。谢谢你的快速回答,你能解释一下吗?似乎这些排序使用随机访问属性以实现效率,例如在合并排序中,您将如何访问列表的中间部分?您必须运行n/2 stepsQuicksort,但不能以与数组相同的效率在单链表上运行。@incrediman:为什么不能?从列表中选取第一个作为轴心,然后遍历其余部分,构建两个新列表。将这两个列表排序。把它们拼接在一起。实际上,使用链表比使用数组更容易。(我承认mergesort是错的)不过拼接O(n)不是吗?如果没有,您必须跟踪列表中每个列表的长度,这当然也不会有效率。如果您可以用伪代码为单链接列表编写一个快速排序实现,演示其效率如何与数组上的快速排序相同,这将非常有用。*您必须跟踪