IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> python排序算法(六)、希尔排序 -> 正文阅读

[数据结构与算法]python排序算法(六)、希尔排序

插入排序:

假如有一个列表[5, 7, 4, 6, 3, 1, 2, 9, 8],将此列表当作桌子上的牌,最开始我们手里有一张牌5, 此时我们依次从剩余的牌[7, 4, 6, 3, 1, 2, 9, 8]中摸出牌来与手中的牌进行对比,手里的牌只要大于摸到的牌则往右走,最后将摸到的牌插入到合适的位置

插入排序代码:

def insert_sort(li):
    for i in range(1, len(li)):  # i 代表我即将摸到牌的下标[7, 4, 6, 3, 1, 2, 9, 8]
        tmp = li[i]  # 代表我当前摸到的牌
        k = i - 1  # 表示我现在手里的牌的数量[0 - k]
        while k >= 0 and li[k] > tmp:  # 循环从右遍历手里的牌,如果当前手里的牌大于摸到的牌,则将手里的牌放到摸到的牌的位置
            li[k + 1] = li[k]
            k -= 1
        li[k + 1] = tmp # 最后对比完手里的牌将摸到的牌放到合适的位置

而希尔排序(shell Sort)是一种分组插入排序算法。

希尔排序的具体思路步骤:(n等于列表的长度)

  • 首先取一个整数d1 = n // 2 ,将元素分为d1个组,每组相邻元素之间的距离为d1,在各组内进行插入排序
  • 取第二个整数d2 = d1 // 2 ,重复上述分组排序,则到di =1时,即所有元素在同一组内进行插入排序即可完成排序
  • 希尔排序每趟并不是使某些元素有序,而是使整体数据越来越接近有序;最后一趟排序使得所有数据有序

这里取列表 [5, 7, 4, 6, 3, 1, 2, 9, 8]?

第一次分组d1 = 9 // 2 = 4 ,分成4组,依次对[5, 3, 8],? [7, 1],? [4,2], [6,9] 进行插入排序? ? ? ? ?

574631298
538
71
42
69

这里我们可以将 5,7,4,6看成手里的牌, 即将摸到的牌为 3,1,2,9,8。5与3比较,7与1比较,4 与 2 比较, 6 与 9 比较。元素之间间隔4个下标。 依次下一列比较

第一次分组插入排序后:[3, 1, 2, 6, 5, 7, 4, 9, 8]

第二次分组 d2 = d1 // 2 =2, 依次对[3,2,5,4,8]、[1,6,7,9]进行插入排序

312657498
32548
1679

第二次分组插入排序后:[ 2,1,3,6,4,7,5,9,8 ]

第三次分组 d3 = d2 // 2 =1 则对?[ 2,1,3,6,4,7,5,9,8 ]进行插入排序,排序后[1, 2, 3, 4, 5, 6, 7, 8, 9]

代码?

def insert_sort_gap(li, gap): # gap 代表分成机组
    for i in range(gap, len(li)):
        tmp = li[i]  # 第一组中即将摸的牌
        k = i - gap  # 第一组中手里有的牌
        while k >= 0 and li[k] > tmp:  # 摸到的牌大于手里的牌
            li[k + gap] = li[k] # 手里的牌交换到摸到的牌的位置
            k -= gap
        li[k + gap] = tmp # 将摸到的牌放到合适的位置
    print(li)


def shell_sort(li):
    d = len(li) // 2
    while d >= 1:
        insert_sort_gap(li, d)
        d //= 2


li = [5, 7, 4, 6, 3, 1, 2, 9, 8]
shell_sort(li)
print(li)

插入排序和希尔排序对比

import random
import time
import copy


def cal_time(func):
    def inner(*args, **kwargs):
        strat = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print('%s执行时间:%s' % (func.__name__, end - strat))
        return result

    return inner


@cal_time
def insert_sort(li):
    for i in range(1, len(li)):  # i 代表我即将摸到牌的下标[7, 4, 6, 3, 1, 2, 9, 8]
        tmp = li[i]  # 代表我当前摸到的牌
        k = i - 1  # 表示我现在手里的牌的数量[0 - k]
        while k >= 0 and li[k] > tmp:  # 循环从右遍历手里的牌,如果当前手里的牌大于摸到的牌,则将手里的牌放到摸到的牌的位置
            li[k + 1] = li[k]
            k -= 1
        li[k + 1] = tmp  # 最后对比完手里的牌将摸到的牌放到合适的位置


def insert_sort_gap(li, gap):  # gap 代表分成机组
    for i in range(gap, len(li)):
        tmp = li[i]  # 第一组中即将摸的牌
        k = i - gap  # 第一组中手里有的牌
        while k >= 0 and li[k] > tmp:  # 摸到的牌大于手里的牌
            li[k + gap] = li[k]  # 手里的牌交换到摸到的牌的位置
            k -= gap
        li[k + gap] = tmp  # 将摸到的牌放到合适的位置
    # print(li)


@cal_time
def shell_sort(li):
    d = len(li) // 2
    while d >= 1:
        insert_sort_gap(li, d)
        d //= 2


#
# li = [5, 7, 4, 6, 3, 1, 2, 9, 8]
# shell_sort(li)
# print(li)
li = list(range(10000))
random.shuffle(li)

li1 = copy.deepcopy(li)
li2 = copy.deepcopy(li)

shell_sort(li1)
insert_sort(li2)

# 结果
shell_sort执行时间:0.013513565063476562
insert_sort执行时间:1.416457176208496

插入排序的时间复杂度为:O(n2)

希尔排序的时间复杂度为:

? ? ? ? 最坏:O(n2)

? ? ? ? 平均情况:O(n2) -- O(n)

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:52:38  更:2022-09-21 00:55:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 21:15:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码