归并排序
归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)
策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
(1)稳定性
归并排序是一种稳定的排序。
(2)时间复杂度
对长度为n的文件,需进行趟二路归并,每趟归并的时间为O(n),故其时间复杂度是O(nlgn)。
(3)空间复杂度
需要一个辅助数组来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n)。
图解归并两个有序子文件的过程:
代码:
-- 分治法 先分后治 治:归并
-- 使用辅助空间对两个有序的数组排序
local function Merge(a, left, mid, right)
-- body
-- i, j, t:合并的两个序列和辅助表的指针 temp 辅助表
local i, j, t, temp = left, mid+1, 1, {}
-- 使用辅助表对两个序列进行归并排序
while i <= mid and j <= right do
if a[i] < a[j] then
temp[t] = a[i]
i = i + 1
else
temp[t] = a[j]
j = j + 1
end
t = t + 1
end
-- 填充剩余的数
while i <= mid do
temp[t] = a[i]
t = t + 1
i = i + 1
end
while j <= right do
temp[t] = a[j]
t = t + 1
j = j + 1
end
-- 将辅助表数据copy到原数组中
for k,v in ipairs(temp) do
a[left+k-1] = v
end
end
-- 归并算法
local function mergeSort(a, left, right)
-- body
-- “分”的临界条件
if left < right then
local mid = math.modf((left + right) / 2)
-- 分
mergeSort(a, left, mid)
mergeSort(a, mid + 1, right)
-- 治
Merge(a, left, mid, right)
end
end
local a = {0, 8, 9, 2, 7, 6, 3, 1}
mergeSort(a, 1, #a)
for k,v in ipairs(a) do
print(k,v)
end
结果:
1 0
2 1
3 2
4 3
5 6
6 7
7 8
8 9