【Python】Python基础排序算法实现

来源:互联网 发布:python高级编程第3版 编辑:程序博客网 时间:2024/06/05 11:00

前言

这段时间为了准备找数据分析师相关的工作,特用Python将基本的排序算法进行实现,以达到巩固的目的。

Python有自己的列表排序方法,就是sorted函数和sort()函数,区别是:
  • sorted函数返回一个有序的序列副本,返回排序的结果则表示创建了一个副本;
  • sort()函数直接在当前列表进行排序,不创建副本,故sort()函数返回None。一般来说,返回None表示是在原对象上进行操作。
常用的排序算法(主要指面试中)包含两大类,
  1. 基于比较的排序(comparison-based sorting),是建立在两个数(comparable)进行对比得出大小的基础上,可分成两类:
    • 基于数组的
      • 插入排序
      • 希尔排序
      • 冒泡排序
      • 快速排序
      • 选择排序
      • 归并排序
    • 基于树的
      • 堆排序
      • 二叉树排序
  2. 基于非比较模型的排序
    • 桶排序
    • 位图排序

一、插入排序(Insertion sort)

时间复杂度:O(n²),稳定
基本思想:把序列的第一个元素当成已排序列表中的元素,接着从第二个元素开始,与已排序列表中的元素一一比较,并放到合适的位置。
from numpy import sortdef insert_sort(nums):    nums_length=len(nums)        if nums_length<2:        return nums    for i in range(1, nums_length):        tmp=nums[i]        j=i-1        while j>=0 and tmp<nums[j]:            nums[j+1],nums[j]=nums[j],nums[j+1]            j = j - 1    return nums    if __name__=='__main__'    nums=[34,8,64,51,32,21]    print('unsorted nums:',nums)    insert_sort(nums)    print('sorted nums:',nums)

二、希尔排序(Shell sort)

时间复杂度:o(n ²),不稳定
基本思想:插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。该方法因DL.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
def shell_sort(nums):    m = len(nums) # 元素数目    gap = m//2     # gap = 5,2,1...    while gap > 0:        # print (gap)        for i in range(m):            index = i            j = i+1            while j < m:                if nums[j] < nums[index]:                    index = j                j += gap            if index != j:  # 若有元素比list[i]小,交换                nums[index], nums[i] = nums[i], nums[index]            # print (list)        gap = gap // 2    return nums

三、冒泡排序(Bubble sort)

时间复杂度:O(n²),稳定
基本思想:比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
def bubble_sort(nums):    # 冒泡排序    count = len(nums)    for i in range(0, count):        for j in range(i + 1, count):            if nums[i] > nums[j]:                nums[i], nums[j] = nums[j], nums[i]    return nums

四、快速排序(Quick sort)

时间复杂度:O(nlogn),不稳定
基本思想:快速排序是一种分治思想,基本思想是先随便在无序列表中找一个元素,以这个元素为基准,其他所有元素都跟该元素比,比该元素小的成为一个子序列,比该元素大的成为另一个子序列,接着重复此过程,最终达到排序效果。
def sub_sort(nums, low, high):    key = nums[low]    while low < high:        while low < high and nums[high] >= key:            high -= 1        while low < high and nums[high] < key:            nums[low] = nums[high]            low += 1            nums[high] = nums[low]    nums[low] = key    return lowdef quick_sort(nums, low, high):     if low < high:        key_index = sub_sort(nums, low, high)        quick_sort(nums, low, key_index)        quick_sort(nums, key_index + 1, high)if __name__ == '__main__':    nums = [10, 8, 4, -1, 2, 6, 7, 3]    print('nums is:', nums)    quick_sort(nums,0,len(nums)-1)    print('insert sort:', nums)

五、选择排序(Selection sort)

时间复杂度:O(n²),不稳定
基本思想:从未排序的序列中找到一个最小的元素,放到第一位,再从剩余未排序的序列中找到最小的元素,放到第二位,依此类推,直到所有元素都已排序完毕。
def selection_sort(nums):    list_length=len(nums)    for i in range(0,list_length-1):        for j in range(i+1,list_length):            if nums[i]>nums[j]:                nums[i], nums[j]= nums[j], nums[i]    return nums

六、归并排序(Merge sort)

时间复杂度:O(nlogn),稳定
基本思想:归并排序是一种典型的分治思想,把一个无序列表一分为二,对每个子序列再一分为二,继续下去,直到无法再进行划分为止。然后,就开始合并的过程,对每个子序列和另外一个子序列的元素进行比较,依次把小元素放入结果序列中进行合并,最终完成归并排序。

七、堆排序(Heap sort)

时间复杂度:O(nlogn),不稳定
基本思想:先建立一个最大堆,在建立最大堆的过程中需要不断调整元素的位置。最大堆建立后,顶端元素必定是最大的元素,把该最大元素与最末尾元素位置置换,最大元素就出现在列表末端。重复此过程,直到排序。

八、桶排序(Bucket sort)

时间复杂度:O(n+c),c=n*(logn-logm),稳定
基本思想: