📜  Julia 中的数组排序

📅  最后修改于: 2022-05-13 01:55:28.818000             🧑  作者: Mango

Julia 中的数组排序

以特定顺序或方式排列给定数据的过程取决于输出。它是按排序顺序存储数据。排序可以通过两种方式进行,即升序和降序。可以使用排序算法或排序函数来执行排序。因此,在对程序进行排序时,搜索最小数字并根据算法将该数字移动到数组或列表的开头。
数组在排序时起着非常关键的作用。它们用于存储必须排序的元素列表。

Julia 中的排序技术

Julia 中共有 4(四种)排序算法,它们是:

  • 插入排序
  • 快速排序
  • 部分快速排序(k)
  • 合并排序

插入排序

这种排序技术一次遍历集合一个元素,将每个元素插入到输出列表中正确的排序位置。
InsertionSort 是一种 O(n^2) 稳定的排序算法。它对于非常小的 n 是有效的,并且由 QuickSort 在内部使用。

快速排序

QuickSort 非常快,主要用作默认排序算法,但不稳定。这里稳定的意思是“即被认为相等的元素将不会保持它们最初出现在要排序的数组中的相同顺序”。
而且如上所述,它是默认算法,但仅适用于浮点数和整数的数值。
另一方面,如果我们谈论PartialQuickSort(K) ,它类似于 QuickSort,但唯一的区别是如果 K 是整数或在 K 的范围内,则数组将被排序到 K。
例如:

Python3
x = rand(1:500, 100)


Python3
k = 50
k2 = 50:100


Python3
s = sort(x; alg=QuickSort)


Python3
ps = sort(x; alg=PartialQuickSort(k))
qs = sort(x; alg=PartialQuickSort(k2))


Python3
sort!(v, alg=QuickSort)


Python3
defalg(v::AbstractArray) = MergeSort
defalg(v::AbstractArray{<:Number}) = QuickSort


Python3
sort([2, 3, 1])


Python3
sort([2, 3, 1], rev=true)


Python3
r = rand(100:110, 10)
sortperm(r)


Python3
sortrows([7 3 5; -1 6 4; 9 -2 8])


Python3
sortrows([7 3 5; -1 6 4; 9 -2 8], lt=(x, y)->isless(x[2], y[2]))


Python3
sortrows([7 3 5; -1 6 4; 9 -2 8], rev=true)


Python3
sortcols([7 3 5; 6 -1 -4; 9 -2 8])


Python3
sortcols([7 3 5; 6 -1 -4; 9 -2 8],
         alg=InsertionSort, lt=(x, y)->isless(x[2], y[2]))


Python3
sortcols([7 3 5; 6 -1 -4; 9 -2 8], rev=true)


Python3
r = ["1E10", "150", "25", "3", "1.5", "1E-10", "0.5", ".999"];


Python3
sort(r)


Python3
sort(r, by = x -> Meta.parse(x))


Python3
sentence = split("Lorem ipsum dolor sit amet,
consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
 
sort(sentence, lt = (x, y) -> vowelcount(x) > vowelcount(y))


Python3
table = ["F" "B" "I"; "A" "D" "G"; "H" "C" "E"]


Python3
sortslices(table, dims=1)


Python3
sortslices(table, dims=2)


Python3
sortslices(table, dims=1, by = x -> x[2])


所以首先我们创建了包含 100 个元素的随机数组并将其存储在 x 中。

Python3

k = 50
k2 = 50:100

然后我们分配了k的值,k2

Python3

s = sort(x; alg=QuickSort)

然后我们应用了 QuickSort 并对数组 x 进行排序,您可以看到上面的输出。

Python3

ps = sort(x; alg=PartialQuickSort(k))
qs = sort(x; alg=PartialQuickSort(k2))

然后我们使用具有不同 k 值的 PartialQuickSort 并对数组进行排序。首先根据 k 的值对数组的前 50 个值进行排序,然后根据 k2 的值对数组的后 50 个值进行排序,如上所示

合并排序

现在,如果我们看到这种排序算法,其复杂度在 O(n log n) 中,这是一种更稳定的排序算法。但它还需要一个临时数组,并且是给定/输入数组大小的一半。 MergeSort 不如 QuickSort 快。它也是非数值的默认算法。
这完全取决于程序员他想使用哪种排序算法,他可以根据他/她的语法进行更改。
==>选择默认算法是基于它们快速且稳定的。如前所述,选择快速排序是因为它更快。稳定性属性的成本不可忽略,因此如果您不需要它,您可能需要明确指定您的首选算法,

Python3

sort!(v, alg=QuickSort)

==>Julia 选择默认排序算法的机制是通过 Base.Sort.defalg()函数实现的。它允许将特定算法注册为特定数组的所有排序函数中的默认值。例如,以下是 sort.jl 中的两个默认方法:

Python3

defalg(v::AbstractArray) = MergeSort
defalg(v::AbstractArray{<:Number}) = QuickSort

==>对于数值数组,为稳定排序的概念没有意义的数组类型选择一个不稳定的默认算法(即当两个比较相等的值无法区分时)可能是有意义的。

用于排序的函数

排序()函数

此函数返回排序后的数组或数组的排序副本。让我们借助一个例子更清楚地理解它:
示例 1:

Python3

sort([2, 3, 1])

输出:

在上面的例子中,我们可以清楚地看到我们在 sort函数中传递了未排序的数组,作为回报,我们得到了排序后的数组的副本。
并且还可以在 Julia 中对数组进行反向排序。
示例 2:

Python3

sort([2, 3, 1], rev=true)

输出:

sortperm()函数

这个函数也像 sort() 一样工作,但它不是返回它的副本,而是返回一个索引列表,人们可以使用该列表来生成一个排序的集合。
例子:

Python3

r = rand(100:110, 10)
sortperm(r)

让我们正确理解上面的例子,所以在上面的例子中有一个函数rand() 用于生成随机数。我们可以在 rand函数中传递任何数据类型。
句法:

rand([rng=GLOBAL_RNG], [S], [dims...])

然后,当我们在 sortperm() 中传递集合时,我们可以观察生成索引的第一个输出,然后再次传递这些索引,如示例所示,我们可以获得所需的输出。

排序()

使用此函数对矩阵行进行字典排序。让我们看看这方面的例子来理解:

Python3

sortrows([7 3 5; -1 6 4; 9 -2 8])

输出:

3×3 Array{Int64, 2}:
 -1   6  4
  7   3  5
  9  -2  8

Python3

sortrows([7 3 5; -1 6 4; 9 -2 8], lt=(x, y)->isless(x[2], y[2]))

输出:

3×3 Array{Int64, 2}:
  9  -2  8
  7   3  5
 -1   6  4

Python3

sortrows([7 3 5; -1 6 4; 9 -2 8], rev=true)

输出:

3×3 Array{Int64, 2}:
  9  -2  8
  7   3  5
 -1   6  4

排序列()

使用此函数对矩阵行进行字典排序。
例子:

Python3

sortcols([7 3 5; 6 -1 -4; 9 -2 8])

输出:

3×3 Array{Int64, 2}:
  3   5  7
 -1  -4  6
 -2   8  9

Python3

sortcols([7 3 5; 6 -1 -4; 9 -2 8],
         alg=InsertionSort, lt=(x, y)->isless(x[2], y[2]))

输出:

3×3 Array{Int64, 2}:
  5   3  7
 -4  -1  6
  8  -2  9

Python3

sortcols([7 3 5; 6 -1 -4; 9 -2 8], rev=true)

输出:

3×3 Array{Int64, 2}:
 7   5   3
 6  -4  -1
 9   8  -2

现在,最大的问题是如果有人想在排序集合时定义自己的函数而不是 sort()函数怎么办。
对上述说法的回答是使用'by''lt'关键字。

排序和比较

因此,通过使用“by”“lt”关键字,可以提供自己的函数并在排序期间比较元素。
sort by :该函数在比较之前对每个元素进行处理,并提供一个用于排序的键。
例子:

Python3

r = ["1E10", "150", "25", "3", "1.5", "1E-10", "0.5", ".999"];

对上面的示例使用默认排序,然后它将按照字符在 Unicode 中出现的顺序对数组进行排序。

Python3

sort(r)

输出:

“0.999”之后出现“1E-10”。
要按数值对数字进行排序,请将 parse()函数传递给 by:

Python3

sort(r, by = x -> Meta.parse(x))

输出:

字符串按其值“按”排序。您提供的 by函数产生数字排序键,但原始字符串元素出现在最终结果中。
您还可以在排序时使用匿名函数。
“小于”函数:
默认情况下,比较元素时使用 isless() 进行排序。但是,排序数组中的第一个元素小于第二个元素。
'lt'函数还用于通过传递可用于比较两个元素的不同函数来更改行为,如果它们已排序则返回 true。
假设我们要根据每个单词中的数字对单词数组进行排序。
例如,单词“orange”将被认为是“小于”单词“lemon”,因为它有更多的元音。
首先我们需要一个计算元音的函数:

vowelcount(string) = count(c -> (c in "aeiou"), lowercase(string))

现在您可以将匿名函数传递给 sort(),该函数使用此函数比较两个元素的元音计数,然后在每种情况下返回具有更高计数的元素:

Python3

sentence = split("Lorem ipsum dolor sit amet,
consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
 
sort(sentence, lt = (x, y) -> vowelcount(x) > vowelcount(y))

结果是元音最多的单词首先出现:

sort()函数还允许您指定反向排序 - 在 'by' 和 'lt' 函数(如果使用)完成它们的工作后,传递给 rev 的真值会反转结果。

对二维数组进行排序

使用 sortslices() 我们可以在 Julia 中对多维数组进行排序。
例如:

Python3

table = ["F" "B" "I"; "A" "D" "G"; "H" "C" "E"]

输出:

3×3 Array{String, 2}:
 "F"  "B"  "I"
 "A"  "D"  "G"
 "H"  "C"  "E"

您向 dims(“dimensions”)关键字提供一个数字或一个元组,以指示您想要排序的内容。要对表进行排序以便对第一列进行排序,请使用 1:

Python3

sortslices(table, dims=1)

输出:

3×3 Array{String, 2}:
 "A"  "D"  "G"
 "F"  "B"  "I"
 "H"  "C"  "E"

请注意,sortslices 返回一个新数组。第一列按字母顺序排列。
使用 dims=2 对表格进行排序,以便对第一行进行排序:

Python3

sortslices(table, dims=2)

输出:

3×3 Array{String, 2}:
 "B"  "F"  "I"
 "D"  "A"  "G"
 "C"  "H"  "E"

现在第一行按字母顺序排列。

如果要按第一项以外的其他内容进行排序,请将函数传递给 by。因此,要对行进行排序以使中间列按字母顺序排列,请使用:

Python3

sortslices(table, dims=1, by = x -> x[2])

输出:

3×3 Array{String, 2}:
 "F"  "B"  "I"
 "H"  "C"  "E"
 "A"  "D"  "G"