'''
Author: sk 2309620371@qq.com
Description:
'''
'''
缩减查找次数,元素移动没有消除
# 版本1 含哨兵版
数组头不好取,可直接建立哨兵
实现细节:\
1、第一层循环 迭代无序首位
2、第二次循环 查找有序中合适的位置\
1、折半怎么折?
mid = (low + high) / 2 #中间
low mid-1 mid mid+1 high #查找后减半序列位置
low > high # 折半查找退出条件 low是可以和high相等的
总结:
1、可以写在循环外的,尽量不要在循环内写,但一定要确保该语句在循环内可有可无
2、判断边界值,是否可以等于的时候,带入计算,减少代价,尽管debug是有效的
'''
from numpy import random
# 由于有哨兵,数组大小存取n个,必须申请空间为n+1
# 算法未处理随机生成的首位元素,可重新生成数组
def halfInsert(nums):
# i 为无序序列第一个元素指针
i = 2
length = len(nums) - 1
j = i-1
while(i<=length):
# !初次未将赋值语句放入循环内,导致哨兵一直未变
nums[0] = nums[i]
# 如果待排序的元素大于或者等于有序末位,直接进入下一层循环
if nums[0] >= nums[j]:
# 有序序列末尾指针后移
j = i
# 无序序列首位指针后移
i = i + 1
continue
else:
low = 1
high = j
mid = 1
# 内循环,查找元素应该插入位置
while(low <= high ):
mid = (low + high) // 2
# 若待排元素大于当前比较元素,low更新mid+1
if nums[0] > nums[mid]:
low = mid + 1
continue
# 若待排元素小于当前比较元素,high更新mid-1
if nums[0] < nums[mid]:
high = mid - 1
continue
# # 若待排元素等于当前比较元素,退出循环
if nums[0] == nums[mid]:
break
# 元素后移 # !初次写的时候没考虑j=mid的情况,导致循环出错
while(j>=mid):
nums[j+1] = nums[j]
j = j - 1
nums[mid] = nums[0]
# 有序序列末尾指针后移
j = i
# 无序序列首位指针后移
i = i + 1
return nums
for i in range(5):
nums = random.randint(100, size=(5))
print(nums)
print(halfInsert(nums))
折半查找排序
最新推荐文章于 2023-03-16 08:54:18 发布