def merge(arr, left, mid, right):
n1 = mid - left + 1
n2 = right - mid
L = arr[left:left + n1]
R = arr[mid + 1:mid + 1 + n2]
i = j = 0
k = left
while i < n1 and j < n2:
if L[i] <= R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1
while i < n1:
arr[k] = L[i]
i += 1
k += 1
while j < n2:
arr[k] = R[j]
j += 1
k += 1
def mergeSort(arr, left, right):
if left < right:
mid = (left + (right - 1)) // 2
mergeSort(arr, left, mid)
mergeSort(arr, mid + 1, right)
merge(arr, left, mid, right)
arr = [12, 11, 13, 5, 6, 7, 88, 45, 42, -5, 56, 55, 41]
n = len(arr)
mergeSort(arr, 0, n - 1)
print("Sorted array is:")
for i in range(n):
print(arr[i], end=" ")
-
函数
mergeSort
接受三个参数:arr
:待排序的数组。left
:当前子数组的左边界(起始索引)。right
:当前子数组的右边界(结束索引)。
-
首先,函数检查
left
是否小于right
。这个条件用于确定是否需要继续拆分当前子数组。如果left
大于等于right
,则说明当前子数组中只有一个元素,它已经是有序的,不需要进一步排序。 -
如果
left
小于right
,则计算中间索引mid
,它将用于将当前子数组分成两部分:arr[left:mid]
和arr[mid+1:right]
。 -
然后,递归地调用
mergeSort
函数两次:- 第一次调用:对左半部分
arr[left:mid]
进行排序,即mergeSort(arr, left, mid)
。 - 第二次调用:对右半部分
arr[mid+1:right]
进行排序,即mergeSort(arr, mid+1, right)
。
- 第一次调用:对左半部分
-
这两次递归调用将继续将当前子数组拆分成更小的子数组,直到每个子数组包含一个或零个元素为止,因为单个元素本身是有序的。
-
一旦所有递归调用完成,开始合并这些子数组。这是通过调用
merge
函数来实现的,merge
函数用于将两个有序的子数组合并为一个有序的数组。 -
最终,当所有递归调用完成并且
merge
函数执行完毕后,整个数组arr
将会以升序的方式排序。 -
merge
函数:这是执行合并操作的函数。它接受四个参数:arr
:待排序的数组。left
:子数组的左边界(起始索引)。mid
:子数组的中间索引,用于分割子数组为左右两部分。right
:子数组的右边界(结束索引)。
-
n1
和n2
:这两个变量用于计算左子数组L
和右子数组R
的长度。n1
表示左子数组的长度,n2
表示右子数组的长度。 -
L
和R
数组:这两个数组分别用于存储左子数组和右子数组。它们是通过切片操作从原始数组arr
中提取的。 -
i
、j
和k
:这三个变量用于遍历和合并左子数组L
和右子数组R
以生成有序的结果数组。i
用于遍历L
,j
用于遍历R
,k
用于指示合并后的数组位置。 -
while
循环:这个循环用于比较左子数组的元素L[i]
和右子数组的元素R[j]
。如果L[i]
小于或等于R[j]
,则将L[i]
放入原始数组arr
中的位置k
,然后递增i
和k
。如果L[i]
大于R[j]
,则将R[j]
放入原始数组arr
中的位置k
,然后递增j
和k
。这个过程重复执行,直到i
和j
分别达到左子数组和右子数组的末尾。 -
两个额外的
while
循环:这两个循环用于处理可能剩余在左子数组L
或右子数组R
中的元素,因为左右两部分的长度可能不相等。这些循环将剩余的元素依次放入原始数组arr
中的位置k
。