python(3)排序

1.插入排序

思路:

初始状态,所有元素无序,假设划分为左右两侧,左侧有序,右侧无序

先遍历右侧无序部分,

再遍历左侧有序部分,

找到在有序的数组中,第一个大于无序元素nums[i]的有序元素nums[j],即为插入位置

nums = [5, 3, 6, 4, 1, 2, 8, 7]
for i in range(1, len(nums)):  # 遍历无序
    for j in range(i):  # 遍历有序
        if nums[j] > nums[i]:  # 找到插入位置
            ins = nums[i]
            nums.pop(i)
            nums.insert(j, ins)
            break
print(nums)

2.选择排序

思路:

初始状态,所有元素无序,假设划分为左右两侧,左侧有序,右侧无序

每次从无序中,找到最小的元素,放到有序的末尾,也就是和无序的第一个元素相交换

nums = [5, 3, 6, 4, 1, 2, 8, 7]
for i in range(len(nums) - 1):  # 更新无序数组的第一个元素的位置
    minInd = i
    for j in range(i, len(nums)):  # 找出未排序数组中最小值的下标
        if nums[j] < nums[minInd]:
            minInd = j
    nums[i], nums[minInd] = nums[minInd], nums[i]  # 把最小值加到有序数组末尾
print(nums)

3.冒泡排序

思路:

重复遍历数组,依次比较相邻的元素,最大数/最小数会慢慢“浮”到数组的末尾。

nums = [5, 3, 6, 4, 1, 2, 8, 7]

for i in range(len(nums), 0, -1):  # 更新本趟遍历确定的元素位置
    # flag用于标记是否有元素交换发生
    flag = 0
    for j in range(i - 1):  # 遍历未排序的数组
        if nums[j] > nums[j + 1]:
            nums[j], nums[j + 1] = nums[j + 1], nums[j]
            flag = 1  # 标记存在元素交换
    if not flag:
        break  # 如果本趟遍历没有发生元素交换,直接跳出循环
print(nums)

4.归并排序

思路:

先把数列拆分为子数列,对子数列进行排序后,再把有序的子数列合并为完整的有序数列

# 归并排序
nums = [5, 3, 6, 4, 1, 2, 8, 7]


def MergeSort(num):
    if len(num) <= 1:  # 递归边界条件
        return num  # 到达边界时返回当前的子数组
    mid = int(len(num) / 2)  # 求出数组的中位数
    llist, rlist = MergeSort(num[:mid]), MergeSort(num[mid:])  # 调用函数分别为左右数组排序
    result = []
    i, j = 0, 0
    while i < len(llist) and j < len(rlist):  # while循环用于合并两个有序数组
        if rlist[j] < llist[i]:
            result.append(rlist[j])
            j += 1
        else:
            result.append(llist[i])
            i += 1
    result += llist[i:] + rlist[j:]  # 把数组未添加的部分加到结果数组末尾
    return result  # 返回已排序的数组


print(MergeSort(nums))

5.快速排序

思路:

取数组中的一个数作为基准值,把所有小于基准值的数都放在它的一侧,再把所有大于基准值的数都放在它的另一侧。随后,对基准值左右两侧的数组分别进行快速排序。

一般情况下,取数组的第一个数作为基准进行快速排序。

(1)移动右边的指针,一直到指针指向的元素小于基准值为止,把右边的指针指向的值2赋给左边的指针指向的位置,这时候,原来2所在的位置实际上是空出来的空位。

 (2)移动左边的指针,等到它指向了一个大于等于基准值的数再停下。类似地,把左边的指针指向的值赋给右边的指针指向的位置。左边指针指向的位置成为空位。

 (3)重复以上步骤,直到左指针和右指针重合,左指针和右指针共同指向的位置就是基准值在有序数组中的位置,它的值大于它左侧的所有元素,并小于等于它右侧的所有元素(如果有相等的元素出现)。

 (4)剩余的步骤为递归地排序左右子数组,直到全部数组排序完毕。

nums = [5, 3, 6, 4, 1, 2, 8, 7]


def QSort(left, right):
    # 子数组第一个元素和最后一个元素在原数组中的位置
    if left >= right:  # 边界条件
        return
    l, r, key = left, right, nums[left]  # 初始化左指针,右指针和基准值
    while l < r:  # 调整元素位置
        while l < r and nums[r] >= key:
            r -= 1
        nums[l] = nums[r]
        while l < r and nums[l] < key:
            l += 1
        nums[r] = nums[l]
    nums[l] = key  # 把基准值赋给左指针和右指针共同指向的位置
    QSort(left, l - 1)  # 左侧数组排序
    QSort(l + 1, right)  # 右侧数组排序


QSort(0, len(nums) - 1)
print(nums)

6.希尔排序

思路:

把数组内的元素按下标增量分组,对每一组元素进行插入排序后,缩小增量并重复之前的步骤,直到增量到达1

(1)使用(数组长度/2)作为初始增量,从第一个元素开始,以增量4来分组。

 (2)继续用相同的方法分组,对组内的元素进行插入排序使得它们有序。

整个数组内的数都被遍历完成后,这一轮排序就结束了。

 (3)把增量缩小一半,继续进行下一轮排序。增量为2时,可以看出每一组内的元素增多了,组的总数减少了。继续对每一组内的元素进行插入排序,直到每一组都遍历完成。

 (4)再次把增量缩小一半;这时增量为1,相当于对整个数组进行插入排序,也就是最后一轮排序。

nums = [5, 3, 6, 4, 1, 2, 8, 7]


def ShellSort(nums):
    step = len(nums) // 2 # 初始化增量为数组长度的一半
    while step > 0:  # 增量必须是大于0的整数
        for i in range(step, len(nums)):
            # 遍历需要进行插入排序的数
            ind = i
            while ind >= step and nums[ind] < nums[ind - step]:  # 对每组进行插入排序
                nums[ind], nums[ind - step] = nums[ind - step], nums[ind]
                ind -= step
        step //= 2 # 增量缩小一半
    print(nums)


ShellSort(nums)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值