算法

冒泡排序

nums = [5, 9, 1, 6, 11, 15, 99, 7]
swap = 0
times = 0
for i in range(len(nums)-1): #趟数控制,比较趟数为总数减一
    times += 1
    swap_flag = True #是否产生交换的状态
    for j in range(len(nums)-1-i): #内层两两比较
        if nums[j] > nums[j+1]:
            nums[j], nums[j+1] = nums[j+1],nums[j]
            swap += 1
            swap_flag = False
    if swap_flag: #一趟下来没有交换则判定顺序已经排好,提前退出循环
        break
    print(nums, times, swap)

核心原则:

  • 每一趟进行两两比较都将一个元素放入有序区。

时间复杂度:O(n2)
当一趟比较下来没有进行交换则可以提前结束排序过程。

简单选择排序

nums = [1, 9, 5, 6, 11, 15, 99, 7]

for i in range(len(nums)-1):#控制循环趟数
    min_index = i #先假定无序区最左元素为本趟的极值
    for j in range(i+1,len(nums)):#内层循环控制被比较元素下标
        if nums[min_index] > nums[j]: #满足极值比较条件则保留新下标j
            min_index = j
    if min_index != i: #如果极值下标没有改变才进行交换
        nums[min_index], nums[i] = nums[i], nums[min_index]
    print(nums)

核心原则:

  • 每趟从无序区选取最大值然后交换到当前无序区最左端。

时间复杂度:O(n2)
原则上比冒泡排序交换次数少所以性能略高于冒泡排序。

双向选择交换

nums = [1, 9, 5, 6]

for i in range(len(nums)//2):#双向选择趟数为元素数整除2
    min_index = i
    max_index = -i-1  #负索引
    for j in range(i+1,len(nums)-i):  #循环记住极值索引
        if nums[min_index] > nums[j]:
            min_index = j
        if nums[max_index] < nums[-j-1]:#-2 -3 -4
            max_index = -j-1
    if min_index == max_index: #两极值下标相等则提前结束
        break
    if min_index != i:
        nums[min_index], nums[i] = nums[i], nums[min_index]
        if i == len(nums) + max_index:  #如果原最小值索引等于即将交换的最大值索引,则调整最大值索引为交换后的负索引
            max_index = min_index - len(nums)
    if max_index != -i-1:
        nums[max_index], nums[-i-1] = nums[-i-1], nums[max_index]
print(nums)

同时选出最大值和最小值放在两端,可以减少趟数。

插入排序

mynums = [1, 6, 5, 3]
nums = [0] + mynums #添加哨兵位
for i in range(2,len(nums)):
    nums[0] = nums[i]
    j = i - 1
    if nums[j] > nums[0]:#有序区最后一位大于哨兵位才进行挪动
        while nums[j] > nums[0]:#选择插入位置,大数依次挪动
            nums[j+1] = nums[j]
            j -= 1
        nums[j+1] = nums[0] #上面循环多减了一次要加回来
print(nums[1:])    
        

核心原则:

  • 将待排数插入到有序区合适的位置
    时间复杂度:O(n2)
    在待排序列前加入一位哨兵位,从索引2开始排序,先将元素放入哨兵位,再插入到有序区合适位置,如果该元素为极值则不变动位置只增大有序区。
posted @ 2021-11-01 11:37  Atlas-777  阅读(48)  评论(0)    收藏  举报