Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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_Haskell - Fatal编程技术网

Algorithm 这是什么排序算法,可以改进吗?

Algorithm 这是什么排序算法,可以改进吗?,algorithm,sorting,haskell,Algorithm,Sorting,Haskell,一段时间以来,我一直在努力制作一个好的排序算法。起初我认为插入排序是个好主意,但对于大列表,它会遇到与Haskell quicksort处理内存类似的问题 然后,我尝试制定自己的排序算法,其工作原理与插入排序相同,但它试图减少内存使用和重复,以提高速度: modsort' :: (Ord a, Eq a) => [a] -> [(a, Int)] modsort' [] = [] modsort' ls@(x:xs) = insert (x, count x ls) $ modsor

一段时间以来,我一直在努力制作一个好的排序算法。起初我认为插入排序是个好主意,但对于大列表,它会遇到与Haskell quicksort处理内存类似的问题

然后,我尝试制定自己的排序算法,其工作原理与插入排序相同,但它试图减少内存使用和重复,以提高速度:

modsort' :: (Ord a, Eq a) => [a] -> [(a, Int)]
modsort' [] = []
modsort' ls@(x:xs) = insert (x, count x ls) $ modsort' (filter (\i -> i /= x) xs)
    where
        insert :: (Ord a, Eq a) => (a, Int) -> [(a, Int)] -> [(a, Int)]
        insert i1 [] = [i1]
        insert i1@(x, _) i2@((y, f):xs)
            | x <= y = i1:i2
            | x >  y = (y, f) : insert i1 xs
        count :: Eq a => a -> [a] -> Int
        count i xs' = count' i xs' 0
            where count' _ [] n = n
                  count' i (x:xs) n
                    | i == x    = count' i xs (n + 1)
                    | otherwise = count' i xs n

uncompress :: [(a, Int)] -> [a]
uncompress [] = []
uncompress ( (v, n) : rest) = repeat' v n ++ uncompress rest
            where repeat' _ 0 = []
                  repeat' i n = i : repeat' i (n - 1)
modsort':(Ord a,Eq a)=>[a]->[(a,Int)]
modsort'[]=[]
modsort'ls@(x:xs)=插入(x,计数x ls)$modsort'(过滤器(\i->i/=x)xs)
哪里
插入::(Ord a,Eq a)=>(a,Int)->[(a,Int)]->[(a,Int)]
插入i1[]=[i1]
插入i1@(x,)i2@((y,f):xs)
|xy=(y,f):插入i1xs
计数::等式a=>a->[a]->Int
计数i x'=计数i x'0
其中,计数“\uu[]n=n
计数i(x:xs)n
|i==x=count'ixs(n+1)
|否则=计数'i xs n
解压::[(a,Int)]->[a]
解压[]=[]
解压((v,n):rest)=重复“v n++解压rest”
其中重复'\u0=[]
重复'inn=i:重复'i(n-1)
与我在网上看到的Haskell的其他一些算法相比,这个算法似乎要长一点。对于重复次数很多的很长的列表(例如,语言:单词、字母),它的伸缩性相当好,但是当列表几乎没有重复时,它会完全失败(Data.list sort能够在2秒内对[10000999..1]进行排序,这花费了50秒)


有没有办法改进这一点或我忽略的一些小事情,或者我应该尝试制作一种不同/更好的排序算法?

这是一种插入算法,对吗?你可以对mergesort算法应用同样的“技巧”。我很好奇:为什么你认为一个次优的O(N^2)算法插入排序是一个好主意呢?合并排序在我看来是一个更好的候选者。这是插入排序输出的“仅”运行长度编码,因此无法更改最坏情况的渐近性(有限字母除外),因为无法保证运行存在。。。但是,如果必须对输出进行运行长度编码,我建议使用
sort'=toAscList实现。fromList
使用该软件包——它将具有最坏情况下的O(n log n)运行时,这是基于比较的排序的最佳选择。@BobDalgleish从我的一条评论中复制过来:“线性时间排序听起来很好,但请在深入研究之前做一些小的基准测试。我本周刚刚玩过它,而且在我的工作中(承认非常简单)测试辨别比
Data.List.sort
使用了更多的内存和时间,一直到我的OOM killer启动的时候,所以尽管它的伸缩性更好,但您可能无法达到重要的伸缩性。“在您的系统上,
Data.List.sort
如何花2秒钟对10000个值进行反向排序?基本上,在任何可以运行Haskell的硬件上,这几乎都是即时的。这是该算法的第二个最佳情况-应该只比调用reverse慢一点。这是一个插入算法,对吗?你可以对mergesort算法应用同样的“技巧”。我很好奇:为什么你认为一个次优的O(N^2)算法插入排序是一个好主意呢?合并排序在我看来是一个更好的候选者。这是插入排序输出的“仅”运行长度编码,因此无法更改最坏情况的渐近性(有限字母除外),因为无法保证运行存在。。。但是,如果必须对输出进行运行长度编码,我建议使用
sort'=toAscList实现。fromList
使用该软件包——它将具有最坏情况下的O(n log n)运行时,这是基于比较的排序的最佳选择。@BobDalgleish从我的一条评论中复制过来:“线性时间排序听起来很好,但请在深入研究之前做一些小的基准测试。我本周刚刚玩过它,而且在我的工作中(承认非常简单)测试辨别比
Data.List.sort
使用了更多的内存和时间,一直到我的OOM killer启动的时候,所以尽管它的伸缩性更好,但您可能无法达到重要的伸缩性。“在您的系统上,
Data.List.sort
如何花2秒钟对10000个值进行反向排序?基本上,在任何可以运行Haskell的硬件上,这几乎都是即时的。这是该算法的第二个最佳情况——它应该只比调用reverse稍微慢一点。