基础排序算法实现

@TOC算法基础实现

1排序

排序算法平均时间复杂度最好情况最坏情况空间复杂度稳定性
选择排序O( n 2 n^2 n2)O( n 2 n^2 n2)O( n 2 n^2 n2)O(1)不稳定
快速排序O(n ln ⁡ n \ln n lnn)O(n ln ⁡ n \ln n lnn)O( n 2 n^2 n2)O( ln ⁡ n \ln n lnn)不稳定
冒泡排序O( n 2 n^2 n2)O(n)O( n 2 n^2 n2)O(1)稳定
插入排序O( n 2 n^2 n2)O(n)O( n 2 n^2 n2)O(1)稳定
希尔排序O(n ln ⁡ n \ln n lnn)O(n ln ⁡ n \ln n lnn)O(n ln ⁡ n \ln n lnn)O(1)不稳定
归并排序O(n ln ⁡ n \ln n lnn)O(n ln ⁡ n \ln n lnn)O(n ln ⁡ n \ln n lnn)O(n)稳定

(1)选择排序

思路:先选一个值作为最小值,然后从剩余的值里面选出来一个更小的,然后交换位置。平均时间复杂度:O( n 2 n^2 n2)

def select_sorted(origin_items):
    """选择排序"""
    items = origin_items[:]
    for i in range(len(items)-1):
        min_index = i
        for j in range(i+1,len(items)):
            if items[j]<items[min_index]:
                min_index = j
        items[i],items[min_index] = items[min_index],items[i]
    return items
if __name__ == '__main__':
    print (select_sorted[2,1,4,6,5]) 


(2)快速排序

思路:选一个值作为基准值,然后从剩余的所有值里面选择比基准值小的放左边,比基准值大的放右边。

def quick_sorted(origin_items):
    """快速排序"""
    if len(origin_items) < 2:
        return origin_items
    #选择中间的数作为基准
    mid_num = origin_items[len(origin_items) // 2]
    #左右两边的数
    left_arr,right_arr = [],[]
    #从原始数组移除中间值
    origin_items.remove(mid_num)
    for item in origin_items:
        if item >= mid_num:
            right_arr.append(item)
        else:
            left_arr.append(item)
    return quick_sorted(left_arr) + [mid_num] + quick_sorted(right_arr)

(3)冒泡排序

思路:每次比较相邻元素,如果第一个比第二个大,就交换位置。外层控制遍数,内层控制趟数。
1.简单版

def bubble_sorted(origin_items):
    """简单冒泡排序"""
    for i in range(1,len(origin_items)):
        for j in range(0,len(origin_items)-i):
            if origin_items[j]>origin_items[j+1]:
                origin_items[j+1],origin_items[j] = origin_items[j+1],origin_items[j]
    return origin_items

2.优化版
如果不发生交换了,结束

def bubble_sorted1(origin_items):
   """优化冒泡排序"""
   for i in range(1,len(origin_items)):
      swapped = False
      for j in range(0,len(origin_items)-i):
         if origin_items[j]>origin_items[j+1]:
            origin_items[j],origin_items[j+1] = origin_items[j+1],origin_items[j]
            swapped=True
      if swapped:
         swapped= False
         for j in range(len(origin_items)-1-i,i,-1):
            if origin_items[j-1] > origin_items[j]:
               origin_items[j],origin_items[j-1] = origin_items[j-1],origin_items[j]
               swapped=True
      if not swapped:
         break
   return origin_items

(4)插入排序

思路:把第一个值作为前一个序列,后面的值作为未排序值,向前面序列找到位置插入。

def insert_sorted(origin_items):
   """插入排序"""
   for i in range(1,len(origin_items)):
      #前一个
      pre = i -1;
      #当前值
      current = origin_items[i]
      #找到合适的位置,插入
      while pre>=0 and origin_items[pre] >=current:
         origin_items[pre+1] = origin_items[pre]
         pre-=1
      origin_items[pre+1] = current
   return origin_items

(5)希尔排序

思路:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序

def shell_sorted(origin_items):
   """希尔排序"""
   n = len(origin_items)
   gab = int(n/2)
   while gab >0:
      for i in range(gab,n):
         temp = origin_items[i]
         j = i
         while j>=gab and origin_items[j-gab] > temp:
            origin_items[j] = origin_items[j-gab]
            j -=gab
         origin_items[j] = temp
      gab = int(gab/2)
   return origin_items

(6)归并排序

思路:分而治之,将大的列表拆分为小的有序列表,再合并为有序列表

def merge_sorted(origin_items):
   """归并排序"""
   if len(origin_items)<2:
      return origin_items
   mid = len(origin_items) // 2
   left_list = merge_sorted(origin_items[:mid])
   print(left_list)

   right_list = merge_sorted(origin_items[mid:])
   print('j')
   return merge(left_list,right_list)
def merge(items1,items2):
   """合并,将两个有序的列表合并为有序的列表"""
   items = []
   index1,index2 = 0,0
   while len(items1)>index1 and len(items2)>index2:
      if items1[index1]<=items2[index2]:
         items.append(items1[index1])
         index1+=1
      else:
         items.append(items2[index2])
         index2+=1
   items += items1[index1:]
   items += items2[index2:]
   return items
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值