zoukankan      html  css  js  c++  java
  • 常用的排序算法解析(插入、希尔、冒泡、选择、归并排序)

    1.插入排序:
    原理:对未排序序列中的每一个数据,在已排序序列中从后向前扫描比较,小于则交换位置,否则结束扫描。
    最坏时间复杂度O(n^2)。
    实现代码:

     1 import random as rm
     2 
     3 
     4 def random_create():
     5 list2 = []
     6 for i in range(100):
     7 list2.append(rm.randint(0, 100))
     8 return list2
     9 
    10 
    11 def sort_x1(listx):
    12 """插入排序,稳定,从第二个数往左边比较插入"""
    13 for i in range(1, len(listx)): # 从1到n所有位置都需要插入操作
    14 for j in range(i, 0, -1): # 从i开始往左比较
    15 if listx[j] < listx[j-1]: # 小于则交换位置
    16 listx[j], listx[j-1] = listx[j-1], listx[j]
    17 else:
    18 break
    19 
    20 
    21 if __name__ == "__main__":
    22 list1 = random_create()
    23 sort_x1(list1)
    24 print(list1)

    2.希尔排序:
    原理:插入算法的一个版本,插入算法是每次扫描相邻的数据进行比较,希尔排序是对数列进行分组,列与列之间跨步比较。
    时间复杂度:O(n^2)
    实现代码:

     1 import random as rm
     2 
     3 
     4 def random_create():
     5 list2 = []
     6 for i in range(100):
     7 list2.append(rm.randint(0, 100))
     8 return list2
     9 
    10 
    11 def sort_x1(listx):
    12 """希尔算法,不稳定排序"""
    13 n = len(listx)
    14 step = int(n/2) # 如果步长大于0,则跨步排序
    15 while step > 0:
    16 for i in range(step, n):
    17 j = i
    18 # 从第一个步长开始判断
    19 while j >= step and listx[j-step] > listx[j]:
    20 # 交换位置
    21 listx[j-step], listx[j] = listx[j], listx[j-step]
    22 j -= step
    23 step = int(step/2) # 新的步长
    24 
    25 
    26 if __name__ == "__main__":
    27 list1 = random_create()
    28 sort_x1(list1)
    29 print(list1)

    3.冒泡排序:
    原理:重复地遍历数列,每次比较两个元素,如果顺序错误则交换,知道不在需要交换为止。
    时间复杂度:O(n^2)
    实现代码:

     1 import random as rm
     2 
     3 
     4 def sort_x1(list1):
     5 """冒泡排序"""
     6 for j in range(len(list1)):
     7 count = 0
     8 for i in range(len(list1) - j - 1): # 比较的次数在递减
     9 if list1[i] > list1[i + 1]:
    10 list1[i + 1], list1[i] = list1[i], list1[i + 1]
    11 count += 1
    12 if count == 0:
    13 return
    14 
    15 return list1
    16 
    17 
    18 def random_create():
    19 list2 = []
    20 for i in range(100):
    21 list2.append(rm.randint(0, 100))
    22 return list2
    23 
    24 if __name__ == "__main__":
    25 list1 = random_create()
    26 sort_x1(list1)
    27 print(list1)

    4.选择排序:
    原理:每次从未排序的数列中通过比较找到最小的那个数,用下标记录下来,然后用它和未排序数列的第一个数交换,每次
    只需要交换一次就能得到一个数据的最终位置。
    时间复杂度:O(n^2)

     1 import random as rm
     2 
     3 
     4 def sort_x1(list1):
     5 """选择排序,不稳定,相同值可能交换位置"""
     6   # 需要进行n-1次选择操作
     7   for i in range(len(list1) - 1):
     8     # 记录最小位置
     9     min_index = i
    10     # 从i+1位置到末尾选择出最小数据
    11     for j in range(i + 1, len(list1)):
    12       if list1[j] < list1[min_index]:
    13         min_index = j
    14     # 如果选择出的数据不在正确位置,进行交换
    15     if min_index != i:
    16       list1[i], list1[min_index] = list1[min_index], list1[i]
    17 
    18 
    19 def random_create():
    20   list2 = []
    21   for i in range(10000):
    22     list2.append(rm.randint(0, 100))
    23   return list2
    24 
    25 if __name__ == "__main__":
    26   list1 = random_create()
    27   sort_x1(list1)
    28   print(list1)

    5.归并排序:
    原理:首先将数组分解成单个数字数组,这时每个数组可以看做有序数组,然后不停地比较合并两个有序数组,直到数组
    有一个为空。
    时间复杂度:O(n^2)
    代码实现:

     1 import random as rm
     2 
     3 
     4 def random_create():
     5   list2 = []
     6   for i in range(100):
     7     list2.append(rm.randint(0, 100))
     8   return list2
     9 
    10 
    11 def sort_x1(listx):
    12 """归并排序"""
    13   # 第一步分解数组,递归
    14   if len(listx) <= 1: # 数组如果为空,或只有一个,返回本身
    15     return listx
    16   n = int(len(listx) / 2)
    17   left_data = sort_x1(listx[:n]) # 递归分解左半边数据
    18   right_data = sort_x1(listx[n:]) # 递归分解右半边数据
    19 
    20   # 合并数据
    21   return add_lr(left_data, right_data)
    22 
    23 
    24 def add_lr(left, right):
    25   """合并数据"""
    26   # 指针记录左右两组下标
    27   l, r = 0, 0
    28   result = [] # 记录结果
    29   while l < len(left) and r < len(right):
    30     if left[l] <= right[r]:
    31       result.append(left[l])
    32       l += 1
    33     else:
    34       result.append(right[r])
    35       r += 1
    36    # 拼接剩余的数据
    37   result += left[l:]
    38   result += right[r:]
    39   return result

      if __name__ == "__main__":
         list1 = random_create()
         sort_x1(list1)
         print(list1)

    6.快速排序:
    原理:每次将数据划分成两个部分,一部分的最大数比另一部分的最小数都要小;一直递归划分下去,直到得到的子数组不能再
    划分为止。
    时间复杂度:O(n^2)
    代码实现:

     1 import random as rm
     2 
     3 
     4 def random_create():
     5   list2 = []
     6   for i in range(100):
     7     list2.append(rm.randint(0, 100))
     8   return list2
     9 
    10 
    11 def sort_x1(listx, st, end):
    12   """快速排序"""
    13   # 判断是否该退出递归
    14   if st >= end:
    15     return
    16   # 设置基准值
    17   mid = listx[st]
    18   # 设置左右移动的游标
    19   low = st
    20   high = end
    21   # 循环判断
    22   while low < high:
    23     # 从右边找到小于基准的值
    24     while low < high and listx[high] >= mid:
    25       high -= 1
    26     listx[low] = listx[high] # 将值赋值给左边游标指向的位置
    27     # 找出左边大于基准的值
    28     while low < high and listx[low] <= mid:
    29       low += 1
    30     listx[high] = listx[low]
    31 
    32     # 循环结束时low=high
    33     listx[low] = mid
    34     # 递归调用函数
    35     sort_x1(listx, st, low-1)
    36     sort_x1(listx, low+1, end)
    37 
    38 
    39 if __name__ == "__main__":
    40   list1 = random_create()
    41   sort_x1(list1, 0, len(list1)-1)
    42   print(list1)

    ps:本文转自博主 天宇之游
  • 相关阅读:
    CLR via C#(11)-无参属性、索引器
    CLR via C#(10)-参数
    C#委托的介绍(delegate、Action、Func、predicate)
    MVC3使用Unity实现接口自动注册
    CLR via C#(09)-扩展方法
    CLR via C#(08)-操作符
    CLR via C#(07)-静态类,分部类
    CLR via C#(06)- 构造器
    VS2010几款超赞的扩展辅助工具总结
    web前端开发随手笔记
  • 原文地址:https://www.cnblogs.com/GP1014336455/p/7693090.html
Copyright © 2011-2022 走看看