如何将归并排序从升序改为降序?遇索引越界问题求助
问题描述
我写的归并排序代码能正常实现数组升序排列,但改成降序时一直报索引越界错误,调试循环逻辑也没找到问题,求解决建议。
我的代码:
def merge_sort(arr, beg, end): if beg < end: mid = (beg + end) // 2 merge_sort(arr, beg, mid) merge_sort(arr, mid + 1, end) merge(arr, beg, mid, end) def merge(A, beg, mid, end): n1 = mid - beg + 1 n2 = end - mid L = [0] * (n1 + 1) R = [0] * (n2 + 1) for i in range(0, n1): L[i] = A[beg + i] for j in range(0, n2): R[j] = A[mid + 1 + j] L[n1] = float('inf') R[n2] = float('inf') i = 0 j = 0 for k in range(beg, end + 1): if L[i] <= R[j]: A[k] = L[i] i += 1 else: A[k] = R[j] j += 1 return A myList = [26,54,93,17,77,31,44,55,20] merge_sort(myList, 0, len(myList) - 1) print(myList)
升序输出正常:[17, 20, 26, 31, 44, 54, 55, 77,93],期望降序输出:[93, 77, 55, 54, 44, 31, 26, 20, 17]。我把判断条件L[i] <= R[j]改成L[i] > R[j]后触发了索引越界错误。
问题分析与解决
错误根源:升序时用
float('inf')当哨兵没问题,因为所有元素都比它小,循环会先取完真实元素再碰哨兵。但改成降序判断L[i] > R[j]时,float('inf')比所有真实元素都大,会被优先选中,导致其中一个指针(i或j)直接跳到哨兵位置后还继续递增,超出数组真实索引范围,触发越界错误。修复方案:把哨兵值换成负无穷
float('-inf'),这样在降序比较时,所有真实元素都比哨兵大,循环会先取完两边的真实元素,不会提前触发哨兵的选取,自然就不会出现索引越界。
修复后的merge函数代码:
def merge(A, beg, mid, end): n1 = mid - beg + 1 n2 = end - mid L = [0] * (n1 + 1) R = [0] * (n2 + 1) for i in range(0, n1): L[i] = A[beg + i] for j in range(0, n2): R[j] = A[mid + 1 + j] # 替换哨兵为负无穷,适配降序逻辑 L[n1] = float('-inf') R[n2] = float('-inf') i = 0 j = 0 for k in range(beg, end + 1): # 降序判断条件 if L[i] > R[j]: A[k] = L[i] i += 1 else: A[k] = R[j] j += 1 return A
- 验证结果:运行修改后的代码,输出正好是期望的降序数组:
[93, 77, 55, 54, 44, 31, 26, 20, 17]。
内容的提问来源于stack exchange,提问作者Jasmine
相关产品推荐
相关产品推荐

