六大排序

## 1.冒泡排序

```python

# 2 冒泡排序:它重复的走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,走访数列的工作是重复的执行到没有再需要交换,也就是说该数列已经完成排序。

#时间复杂度 O(n^2)

#空间复杂度:O(1)

#稳定性:稳定

def bubble_sort(blist):

    count = len(blist)

    for i in range(0,count):

        for j in range(i+1,count):

            if blist[i] > blist[j]:

                blist[i],blist[j] = blist[j],blist[i]

    return blist

print(bubble_sort([4,5,6,7,8,2,3,1,0]))

```

___

## 2.插入排序

```python

#1 插入排序:插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的,个数加1 的有序数据,算法用于少量数据的排序,首先将第一个作为已经排好序的,然后每次从后的取出插入到前面并排序。

#时间复杂度 O(n^2)

#空间复杂度:O(1)

#稳定性:稳定

def insert_sort(ilist):

    for i in range(len(ilist)):

        for j in range(i):

            if ilist[i] < ilist[j]:

                ilist.insert(j,ilist.pop(i))

                break

    return ilist

print(insert_sort([4,6,7,3,2,1,8,0]))

```

___

## 3.选择排序

```python

#3 选择排序 : 第一趟,在待排序记录r1 。。。r(n)中选出最小的记录,将它与r1 交换,第二趟,在待排序记录r2 ~ r(n) 中选出最小的记录,将它与 r2 交换,以此类推,第i趟在待排序记录 r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。

#时间复杂度 O(n^2)

#空间复杂度:O(1)

#稳定性:不稳定

def select_sort(slist):

    #外层循环控制循环次数

    for i in range(len(slist)):

        #假设找到的最小元素下标为j

        x = i

        #寻找最小元素的过程

        for j in range(i,len(slist)):

            #假设最小下标的值,大于循环中一个元素,那么就改变最小值的下标

            if slist[j] < slist[x]:

                x = j

        #循环一开始就假设把最小值的下标赋值给变量 x

        # 在不停的循环中,不停的交换两个不一样大小的值

        slist[i],slist[x] = slist[x],slist[i]

    #返回 排好序的列表

    return slist

if __name__ == '__main__':

    arrayList = [4,5,6,7,3,2,6,9,8]

    select_sort(arrayList)

    print(arrayList)

```

___

## 4.希尔排序

```python

#4 希尔排序 : 希尔排序 是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰好被分成一组,算法终止

#时间复杂度 O(n^2)

#空间复杂度:O(nlogn)

#稳定性:不稳定

def shell_sort(slist):

    count = len(slist)

    step = 2

    group = count // step

    while group>0:

        for i in range(group):

            j = i + group

            while j < count:

                key = slist[j]

                k = j - group

                while k >= 0:

                    if slist[k] > key:

                        slist[k+group] = slist[k]

                        slist[k] = key

                    k = k - group

                j = j + group

        group = group // step

    return slist

# print(shell_sort([4,5,7,3,2,6,9,8,0]))

def ShellSort(arrList):

    arrayLen = len(arrList)

    h = 1

    while h < arrayLen//3:

        h = h * 3 + 1

        #插入排序的方法,判断是不是后一个比前一个要小

        #如果是则交换

    while h >= 1:

        for i in range(h,arrayLen):

            j = i

            while j >= h and arrList[j] < arrList[j-h]:

                arrList[j] ,arrList[j-h] = arrList[j-h],arrList[j]

                j -= h

        h  //= 3

if __name__ == '__main__':

    arrList = [14,33,27,10,35,19,42,44]

    ShellSort(arrList)

    print(arrList)

```

___

## 5.归并排序

```python

#      当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。

"""

归并排序:采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并

时间复杂度:O(nlog₂n)

空间复杂度:O(1)

稳定性:稳定

"""

# 归并排序 Merge_Sort

def MergeSort(arrayList):

    arrayLen = len(arrayList)

    #判断输入参数的正确性,如果长度小于1,就说明为1

    if arrayLen <= 1:

        return arrayList

    midIndex = arrayLen//2

    #左边的部分去做 MergeSort

    leftArray = MergeSort(arrayList[:midIndex])

    #右边的去做 MergeSort

    rightArray = MergeSort(arrayList[midIndex:])

    #将左右两边合并,称为一个新的数组,并已经排序成功

    retArray = MergeCore(leftArray,rightArray)

    return retArray

def MergeCore(leftArray,rightArray):

    #首先需要定义两个指针,这两个指针,分别指向这两个数组的第一个元素

    leftIndex = 0

    rightIndex = 0

    #获取两个数组的长度,用于指出上面两个指针的边界是什么

    leftLen = len(leftArray)

    rightLen = len(rightArray)

    #定义一个返回的列表,这一步就代表空间复杂度至少是 O(n)

    retList = []

    #循环两个数组寻找最小值加入到返回值的数组中

    while leftIndex < leftLen and rightIndex < rightLen:

        if leftArray[leftIndex] < rightArray[rightIndex]:

            retList.append(leftArray[leftIndex])

            leftIndex += 1

        else:

            retList.append(rightArray[rightIndex])

            rightIndex += 1

    #下面的代码是将剩余的数组中内容放置在返回的数组中

    retList.extend(leftArray[leftIndex:])

    # while leftIndex < leftLen:

    #    retList.append(leftArray[leftIndex])

    #    leftIndex += 1

    retList.extend(rightArray[rightIndex:])

    # while rightIndex < rightLen:

    #    retList.append(rightArray[rightIndex])

    #    rightIndex += 1

    return retList

if __name__ == '__main__':

    # 14,33,27,10,35,19,42,44

    retList = MergeSort([14,33,27,10,35,19,42,44])

    print(retList)

```

___

## 6.快速排序

```python

"""

快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

时间复杂度:O(nlog₂n)

空间复杂度:O(nlog₂n)

稳定性:不稳定

"""

#快排的主函数,传入参数为一个列表,左右两端的下标

def QuickSort(array,leftIndex=0,rightIndex=None):

    #数组的长度

    arrayLen = len(array)

    #长度为1 的话 或者 空 的话 直接返回 数组

    if arrayLen <= 1:

        return array

    #程序一开始 如果没有给一个最右边的索引值导入话,那么我们就给它 赋值一个 就是数组的最右边的 那个索引值。

    if rightIndex == None:

        rightIndex = arrayLen - 1

    # 保护条件,只有满足  左边索引小于右边索引的时候 再开始排序

    if leftIndex < rightIndex:

        #找到 基准的 索引值 传入参数,通过Partitions函数,获取k下标值

        pivot = partition(array,leftIndex,rightIndex)

        #递归前后半区 对基准前面不部分继续快排

        QuickSort(array,leftIndex,pivot - 1)

        #对基准后半积分继续快排

        QuickSort(array,pivot + 1,rightIndex)

def partition(array,leftIndex,rightIndex):

    pivotValue = array[rightIndex]

    #将最左侧的 索引值 给 i

    i  = leftIndex

    #将最右侧的 索引的前一个 给j

    j = rightIndex -1

    #当left下标,小于right下标的情况下,此时判断二者移动是否相交,若未相交,则一直循环

    while i < j:

        # 当left对应的值大于锚点 基准点 参考值,就一直向左移动

        while j > leftIndex and array[j] > pivotValue:

            j -= 1

        #当left对应的值小于基准点参考值,就一直向右移动

        while i < rightIndex and array[i] <= pivotValue:

            i += 1

        #若移动完,二者仍未相遇则交换下标对应的值

        if i < j:

            array[j],array[i] = array[i],array[j]

            i+=1

            j-=1

    #若移动完,已经相遇,则交换right对应的值和参考值

    array[i],array[rightIndex] = array[rightIndex],array[i]

    # 返回 一个 索引值

    return i

# 《算法导论》中的快排程序

def partition2(array,leftIndex,rightIndex):

    #设置一个 左边的指针位置 为 左侧的 前一个

    i = leftIndex -1

    #遍历 除 基准数之外的 数

    for j in range(leftIndex,rightIndex):

        #比较 遍历的数 和 基准数 ,若是小于基准数 则 换到数组前面去

        if array[j] < array[rightIndex]:

            #交换位置,将遍历的比 基准数小的数 放到 我们指针 的 后一个上,然后 这个时候指针向后移一位。当遍历的数大于我们的基准数的时候,不移动,而且 指针也不发生变化,那么 当我们遍历完一圈以后,把 我们的基准数 放到 索引i 的后一个 位置,那么就形成了 一个 基准数 左边都是比它小的数,基准数右边 都是比它大的数 这样的模式。然后要把 索引 i 的后一个位置 作为基准数 与 原基准数 交换位置,进而可以第二次来 遍历比较。

            array[j],array[i+1] = array[i+1],array[j]

            i += 1

    #遍历完了以后,将 left 位置上的数 和 最后一个 数  即 right 上的数互换位置,就 重置 基准数了。

    array[rightIndex],array[i+1] = array[i+1],array[rightIndex]

    #返回基准的下标

    return i+1

if __name__ == '__main__':

    array = [14,33,27,10,35,19,42,44]

    QuickSort(array)

    print(array)

```

排序内存使用

排序执行时间:

排序复杂度比较:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355