八大排序算法总结Python实现

实现:弹出iframe内嵌页面元素全屏化 一直也没分享有用的东西给大家,今天刚好做一个例子,整理了一下,顺便发给大家。希望多大家有帮助。 弹出iframe内嵌页面元素到父页面并全屏化 iframe和弹窗这些词对于js高手来说都是耳熟能详的东西,作为一个新人来说,还在学习阶段的我就在工作中遇到这么一个奇葩的需求,要在引入的iframe页面里做一个全屏化的功能. 粗略一看,这还不容易,模拟下F11的功能键什么的,于是网上一搜还真有一大... 阅读详情

排序算法

直接插入排序

img

直接插入排序是一种简单的排序算法,基本操作是将一个记录插入到一个有序结果集中,并且在插入数据过程中将前面大于或者小于(取决于升序或者降序)当前要插入的数据向后移动。

def InsertSort(array):
    j = 0
    length = len(array)
    for i in range(1, length):
        if array[i] < array[i - 1]:
            j = i
            while j > 0:
                if(array[j] < array[j - 1]):
                    array[j], array[j - 1] = array[j - 1], array[j]
                    j = j - 1
    return array
  1. 时间复杂度O(n*n)
  2. 额外空间复杂度O(1)
  3. 稳定

希尔排序

img

1.插入排序在待排序列有序时可将插入排序的时间复杂度降至O(n),基于此如果待排记录在进行插入排序之前基本有序则可以降低时间复杂度

2.此外直接插入排序算法比较简单,在n值很小时效率也比较高

基于上述2点改进插入排序->希尔排序。

希尔排序的增量dk取法:

1.Shell 增量序列的递推公式为:

​ ht=⌊N2⌋,hk=⌊hk+12⌋

2.Hibbard 增量序列的通项公式为:

​ hi=2i−1hi=2i−1

Hibbard 增量序列的递推公式为:

                        h1=1,hi=2∗hi−1+1h1=1,hi=2∗hi−1+1

Hibbard 增量序列的最坏时间复杂度为 Θ(N3/2)Θ(N3/2);平均时间复杂度约为 O(N5/4)O(N5/4)。

3.Knuth 增量序列

Knuth 增量序列的通项公式为:

​ hi=12(3i−1)hi=12(3i−1)

增量序列的递推公式为:

​ h1=1,hi=3∗hi−1+1

4.Gonnet 增量序列

Gonnet 增量序列的递推公式为:

​ ht=⌊N2.2⌋,hk=⌊hk+12.2⌋(若h2=2则h1=1)

5.Sedgewick 增量序列

Sedgewick 增量序列的通项公式为: hi=max(9∗4j−9∗2j+1,4k−3∗2k+1)hi=max(9∗4j−9∗2j+1,4k−3∗2k+1)

Sedgewick 增量序列的最坏时间复杂度为 O(N4/3)O(N4/3);

平均时间复杂度约为 O(N7/6)O(N7/6)。

以Knuth 增量序列为基础的希尔排序算法如下:

def ShellSort(array):
    dk, length, j = 0, len(array), 0
    while dk * 3 < length:
        dk = dk * 3 + 1
    while dk > 0:
        for i in range(dk, length):
            if (array[i] < array[i - dk]):
                tmp = array[i]
                j = i - dk
                while j >= 0 and array[j] > tmp:
                    array[j + dk] = array[j]
                    j -= dk
                array[j + dk] = tmp
        dk //= 3
    return array

增量:dk

待排序列长度:length

j:用来处理当前数据对应减去dk的数据

  1. 时间复杂度比较复杂在此不做讨论
  2. 额外空间复杂度O(1)
  3. 不稳定

### 冒泡排序

img

冒泡排序基本过程,比较相邻元素之间的大小关系,在一趟冒泡排序中可以从n个数据中选取最大或最小值(取决于升序还是降序),在循环过程中也就是从剩余的数据中依次选出其中最大或者最小值的过程。

冒泡排序非递归代码如下:

def BubbleSort(array):

    length = len(array)
    for i in range(length - 1):
        for j in range(length - i - 1):
            if array[j] > array[j + 1]:
                array[j], array[j + 1] = array[j + 1], array[j]
    return array

length:数组长度

i:需要循环的次数

j:需要比较的次数

时间复杂度:O(n*n)

额外空间复杂度:O(1)

稳定的排序算法

冒泡排序递归代码如下:

def BubbleSortRecur(array, end):

    if end == 0:
        return
    for i in range(end - 1):
        if array[i] > array[i + 1]:
            array[i], array[i + 1] = array[i + 1], array[i]
    BubbleSortRecur(array, end - 1)

end:表示循环需要比较到的最后一个位置


快速排序

img

快速排序是对冒泡排序的改进,通过一次排序将一个有序序列分成独立的两个部分,一部分比关键字小一部分比关键字大,再分别对其进行排序使得整个记录有序。

快排递归代码:

def QuickSortRecur(array, start, end):
    if start >= end:
        return
    low, high, pivotKey = start, end, array[start]
    while low < high:
        while low < high and array[high] >= pivotKey:
            high -= 1
        array[low], array[high] = array[high], array[low]
        while low < high and array[low] <= pivotKey:
            low += 1
        array[low], array[high] = array[high], array[low]

    QuickSortRecur(array, start, low - 1)
    QuickSortRecur(array, high + 1, end)

lambda版快排代码:

qsortlam = lambda arr: len(arr) > 1 and qsort(list(filter(lambda x: x <= arr[0], arr[1:]))) + arr[0:1] + qsort(list(filter(lambda x: x > arr[0], arr[1:]))) or arr

短代码版:

def quickSort(arr):  
    return [] if arr==[] else quickSort([y for y in arr[1:] if y<arr[0]]) + [arr[0]]+ quickSort([y for y in arr[1:] if y>=arr[0]])

非递归版本:

def partation(array, low, high):
    if low >= high:
        return
    pivotKey = array[low]
    while low < high:
        while array[high] >= pivotKey and low < high:
            high -= 1
        array[high], array[low] = array[low], array[high]
        while array[low] <= pivotKey and low < high:
            low += 1
        array[high], array[low] = array[low], array[high]
    return low

def QuickSortNonRecur(array):
    stack = []
    position = partation(array, 0, len(array) - 1)

    if position - 1 > 0:
        stack.append((0, position - 1))
    if position + 1 < len(array) - 1:
        stack.append((position + 1, len(array) - 1))
    while len(stack):
        low, high = stack[-1]
        stack.remove(stack[-1])
        mid = partation(array, low, high)
        if mid - 1 > low:
            stack.append((low, mid - 1))
        if mid + 1 < high:
            stack.append((mid + 1, high))
    return array

快排属于不稳定排序

平均时间复杂度为O(nlogn)

最差情况复杂度为O(n*n)

额外空间复杂度:O(n)


选择排序

img

选择排序就是在每次比较过程中拿一个值去和该值后边的所有值去比较,选择大的或者小的进行交换的过程。

选择排序代码:

def SelectSort(array):
    if len(array) <= 1:
        return

    length = len(array)
    for i in range(length):
        for j in range(i + 1, length):
            if array[i] > array[j]:
                array[i], array[j] = array[j], array[i]
    return array

选择排序属于不稳定排序算法

时间复杂度O(n*n)

额外空间复杂度为O(1)


堆排序

img

堆定义:简单讲堆是一个完全二叉树,满足根节点大于或小于左子树和右子树,根节点大的叫做大顶堆,反之叫做小顶堆。

堆排序是利用堆的性质,将堆顶作为要排序列的最后一个元素,因为堆顶是极大值。之后调整堆的结构,将后续的每个堆顶作为剩余序列的最后一个元素,直到整个序列只剩一个元素,排序结束。至于调整堆的具体过程在此并不过多描述,请参考算法导论堆排序相关问题。

根据上述想法堆排序可以编写递归版本的堆排序以及非递归版本的堆排序。

非递归版本的堆排序:

def heapAdjast(array, start, leng):
    length, lchild = leng, 2 * start + 1                

    while lchild <= length - 1:
        if lchild + 1 > length - 1:
            if array[lchild // 2] < array[lchild]:
                array[lchild], array[lchild // 2] = array[lchild // 2], array[lchild]
            return
        else:
            tmp = max(array[lchild], array[lchild + 1])
            if tmp <= array[lchild // 2]:
                return
            if tmp == array[lchild]:
                array[lchild // 2], array[lchild] = array[lchild], array[lchild // 2]
                lchild = lchild * 2 + 1                   
            elif tmp == array[lchild + 1]:
                array[lchild // 2], array[lchild + 1] = array[lchild + 1], array[lchild // 2]
                lchild = (lchild + 1) * 2 + 1

def HeapSort(array):
    length = len(array)

    for i in range(length//2, 0, -1):
        heapAdjast(array, i - 1, len(array))
    for i in range(length - 1, 0, -1):
        array[i], array[0] = array[0], array[i]
        heapAdjast(array, 0, i)

*注释:***length需要调整的序列长度, length - 1需要调整的列表最后一个 ,lchild // 2指向根节点

递归版本堆排序:

def adjust_heap(lists, i, size):
    lchild = 2 * i + 1
    rchild = 2 * i + 2
    max = i
    if i < size / 2:
        if lchild < size and lists[lchild] > lists[max]:
            max = lchild
        if rchild < size and lists[rchild] > lists[max]:
            max = rchild
        if max != i:
            lists[max], lists[i] = lists[i], lists[max]
            adjust_heap(lists, max, size)

def heap_sort(lists):
    size = len(lists)
    for i in range(0, (size/2))[::-1]:
        adjust_heap(lists, i, size)
    for i in range(0, size)[::-1]:
        lists[0], lists[i] = lists[i], lists[0]
        adjust_heap(lists, 0, i)

递归版本相对比较容易理解

堆排序时间复杂度,O(nlogn)

空间复杂度:O(1)

不稳定排序


归并排序

img

归并排序是将一个序列拆分成一个一个元素,之后将两两相邻的元素放入一个新的列表中,依次类推最终将两个有序的列表归并成为一个新的列表,返回。

递归归并排序:

def mergeSort(array):
    length = len(array)
    if length < 2:
        return array

    mid = length // 2
    left = mergeSort(array[:mid])
    right = mergeSort(array[mid:])

    result = []
    lPoint, rPoint = 0, 0
    while lPoint < len(left) and rPoint < len(right):
        if left[lPoint] < right[rPoint]:
            result.append(left[lPoint])
            lPoint += 1
        else:
            result.append(right[rPoint])
            rPoint += 1
    result += left[lPoint:] + right[rPoint:]
    return result

归并排序平均时间复杂度:O(nlogn)

额外空间复杂度:O(n)

稳定的排序算法


基数排序

基数排序是在桶排序的基础上,首先建立0-9的10个桶,之后分别对需要排序的序列的每个数,将该数的第i位取出,之后将整个数字放进对应的桶中,当每位数字都排列之后整个序列有序。排序方式可以从高位开始也可以从低位开始。

import math

def RadixSort(array, radix=10):
    k = int(math.ceil(math.log(max(array), radix)))
    bucket = [[] for i in range(radix)]
    for i in range(k):
        for j in array:
            bucket[int(j / (radix ** i) % radix)].append(j)
        del array[:]
        for z in bucket:
            array += z
            del z[:]
    return array

八大排序总结

img

VS Code配置MinGW64编译非线性优化库NLopt VS Code用MinGW64编译C++代码安装MSYS2软件并配置非线性优化库NLopt和测试引用库代码的完整具体步骤。:若使用非UCRT版本(如传统MinGW64),替换所有路径中的。库文件会自动安装到MSYS2的。 阅读详情

相关推荐

mbedtls | 01 - 移植mbedtls库到STM32的两种方法

一、mbedtls 开源库 1. mbedtls是什么 Mbed TLS是一个开源、可移植、易于使用、代码可读性高的SSL库。可实现加密原语,X.509证书操作以及SSL / TLS和 DTLS 协议,它的代码占用空间小,非常适合用于嵌入式系统。 mbedtls遵循 Apache 2.0 开源许可协议,目前由 TrustedFirmware 维护(Linaro主持的一个治理开放社区项目),在Github上已收获 2.6k star,目前Github上发布的最新版本为 2.24.0 版本,开源仓库地址为:

Mculover666的博客(嵌入式) 1万+

希尔排序增量序列简介

希尔排序可谓是时间复杂度较难分析的一类排序算法之一,其原因在于其增量序列的多样性和构造的复杂性。下面笔者将对几种流传较广的希尔排序的增量序列进行简单的介绍并给出它们的实现代码。

Foliciatarier的博客 1万+

tradingview2024

tradingview2024

排序<3>希尔排序(基于Sedgewick增量序列

1.什么是希尔排序 2.希尔排序的关键点 3.希尔排序怎么用 typedef int ElmentType; void ShellSort(ElmentType S[], int N) { int Si,d; /* 这里只列出一小部分增量 */ int Sedgewick[] = {260609,146305,64769,36289, 16001,8929,3905,2161,929, 5...

Deep_win的博客 2210

希尔排序(带你原理到实践)

除了上述两种常用的增量序列外,还可以根据具体的应用场景和需求来自定义增量序列。例如,可以根据数据的特性或分布来选择合适的增量,或者通过实验来找到最优的增量序列。需要注意的是,选择合适的增量序列并没有固定的规则或标准。通常需要根据具体的数据集、排序要求(如稳定性、时间复杂度等)以及实验结果来做出决策。因此,在实际应用中,可能需要尝试不同的增量序列来找到最适合特定场景的解决方案。希尔排序是一种基于插入排序的改进算法,通过引入增量序列来提高排序效率。

2303_79387663的博客 2296

Java 与排序算法(4):希尔排序

希尔排序(Shell Sort)是插入排序的改进版,由 Donald Shell 在 1959 年提出。希尔排序通过将待排序序列分成多个子序列,分别进行插入排序,最后再进行一次整体的插入排序,从而提高了排序效率。希尔排序的基本思想是将待排序序列分成若干个子序列,对每个子序列进行插入排序,使得整个序列在插入排序的基础上更加有序。具体来说,希尔排序的实现过程如下:选择一个增量序列,通常为 n/2、n/4、n/8 等,其中 n 为待排序序列的长度。

暗星涌动 1758

数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列

数据结构与算法——希尔排序(引例、希尔增量序列、原始希尔排序、代码、时间复杂度、Hibbard增量序列、Sedgewick增量序列) 可以发现,8、4、2间隔的插入排序并没有给序列成功排序,最后还是通过间隔1来完成排序的功能。学习自:MOOC数据结构——陈越、何钦铭。希尔排序在插入排序的基础上进行改进。即表示上界也表示下界,为正常值。-间隔”有序的序列,在执行“-间隔”排序后,仍然是“

li13437542099的博客 1863

弹出iframe内嵌页面元素到父页面并全屏化

(注册博客好久了,一直没舍得添砖加瓦,主要是每次想写点东西的时候,随便搜一搜发现都比我总结的都要好,甚感尴尬,但是总是要开始的,所以这就是我的第一篇博客,也绝不会是最后一篇,废话不多说,直接入正题) ...

setsunadoudou的博客 1739

【原创】在winform程序中实现在IE浏览器中打开一个新的页面,全屏化并屏蔽IE窗口的工具栏和地址栏

查了很多资料和代码,本人历经半天时间才想到一个解决法子。呵呵!~例子:用winform打开一个全屏的newfie.asp页面。首先在新建一个进程,在进程当中运行IE浏览器。 ProcessStartInfo startInfo = new ProcessStartInfo("IExplore.exe"); startInfo.Arguments

linjiancun的专栏 6757

window.open()打开窗口全屏

menubar=no 是否显示菜单栏 scrollbars=no 是否显示滚动【注意: 如果属性fullscreen=yes,则scrollbars=no 没用,必须要设置page.html的,才有用!【注意:如果要在同一个页面中使用window.open( )打开多个窗口,‘page’ 要用空(‘’)或者’_blank’代替,否则只能打开一个窗口。‘page’ 弹出窗口的名字(不是文件名),非必须,可用空 ‘’ 代替;resizable=no 是否允许改变窗口大小,yes为允许;

学习 记录 总结 分享 4624

JS实现新打开网页最大化or全屏显示

一个新的小功能,用户希望打开的页面可以全屏显示~唔~不是实现F11那种效果,只是填满任务栏上方的屏幕~ function openwintask(url) { if (url != null) { try { var feature = 'top=0, left=0,toolb

itchiang的专栏 1万+

希尔排序是的

的序列G,对于G中每一个元素,依次执行insertionSort(A, n, g)。因此,其也被称为“缩小增量排序”。大量研究表明,不同的G序列的选取对于排序的性能有着显著的影响。G序列由希尔排序增量序列的一部分逆序得到,比较著名的增量序列有Shell增量序列、Hibbard增量序列、Knuth增量序列Gonnet增量序列、Sedgewick增量序列等。本题要求你使用Knuth增量序列编写这个排序程序,其递推公式为:填写上面的伪代码中的?来完成这个程序。

Tobyo的博客 676

简易Sedgewick希尔排序

希尔排序 希尔排序法(缩小增量法) 属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序的方法。 希尔排序实质是应用增量序列加快插入排序的算法。 希尔排序的好坏主要取决于获取增量序列的方法。 步骤: 1、定义增量序列; 2、按增量序列的间隔选取数组元素; 3、对选取的数组元素进行插入排序,缩小增量值; 重复步骤3,直到增量序列=1; 增量序列种类: 原始希尔排序增量:第一次 D1=M(数组长度)/2; 后序:Dk=Dk+1      &

qq_41939099的博客 1042

采用Sedgewick增量序列 ShellSort

#include<bits/stdc++.h> using namespace std; void ShellSort(int A[], int N) { int Sedgewick[]= {929, 505, 209, 109, 41, 19, 5, 1, 0}; int si; for (si = 0; Sedgewick[si] >= N; ++si); for (int d = Sedgewick[si]; d > 0; d = Sedgewick[++si])/

fancy_male的博客 826

ReviewForJob——希尔排序(缩小增量排序)之塞奇威克增量序列

【0】README 1)本文旨在给出 希尔排序(缩小增量排序)之塞奇威克增量序列 的源码实现; 2)为什么要求 塞奇威克增量序列?   reason1)要知道, 塞奇威克 提出了几种增量序列,最坏运行时间为 O(N^4/3),平均运行时间为 O(N^7/6); 其提出的增量序列中的最好序列是 {1, 5, 19, 41, 109, ......},该序列中的项或者是 9*4^i - 9*

PacosonSWJTU的博客 2018

数据结构--排序

排序是计算机科学与技术领域中的一项基本操作,旨在将一组数据按某种顺序排列。

weixin_51933701的博客 1907

从Shell到Sedgewick:希尔排序增量演进史及现代应用中的最佳实践

掌握C语言希尔排序的最佳增量选择,提升算法效率。详解从Shell到Sedgewick的增量序列演进,适用于大规模数据预处理与嵌入式系统优化。对比各序列性能优势,提供可直接复用的C代码实现方案,值得收藏。

CompiGlow的博客 605

【算法】希尔排序

希尔排序

weixin_46437504的博客 538

Sedgewick增量希尔排序和快速排序 (附Python代码)

比对结果 随机数组长度为 1000时: Time for heer is 0.08317700000000006 Time for quick is 0.004468999999999945 随机数组长度为10000时: Time for heer is 8.282509 Time for quick is 0.055301000000000045 随机数组长度为20000时: Time...

koko_TT的博客 1274

八大排序算法(原理+代码详解)Python

一、前言: 排序算法是最经典的算法知识,往往面试题中或数据结构中会涉及有关排序的算法,掌握排序算法的思想及其原理有助于化解排序方面的难题。 下面介绍几种Python语言中常见的排序算法: 冒泡排序、选择排序、插入排序、归并排序、快速排序、希尔排序、计数排序。 目录 一、前言: 二、排序算法 (一)冒泡排序 <1>简单介绍 <2>.算法描述: <3>.代码部分 (二)选择排序 <1>简单介绍 <2>算法描述 &l.

Alex_thomas的博客 6727

八大排序算法总结以及python实现

一、概述         排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。         我们这里说说八大排序就是内部排序。          当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。    快速排序

风雪夜归子 1万+
上一篇: Anaconda使用以及常用命令
下一篇: venv入门
wh_585
博客等级 码龄9年 5粉丝 68原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值