Maison >développement back-end >Tutoriel Python >Définition, implémentation et analyse de l'efficacité de la consommation de temps de huit algorithmes de tri courants en Python

Définition, implémentation et analyse de l'efficacité de la consommation de temps de huit algorithmes de tri courants en Python

不言
不言original
2018-04-27 11:05:221230parcourir

Cet article présente principalement la définition, la mise en œuvre et l'analyse de l'efficacité de la consommation de temps de huit algorithmes de tri courants en Python. Il compare également le tri à bulles, le tri par insertion directe, le tri par sélection, le tri par fusion, le tri Hill et le tri par compartiment avec des exemples spécifiques. , le tri par tas et d'autres algorithmes de tri, les amis dans le besoin peuvent se référer à

Cet article décrit la définition, la mise en œuvre et l'analyse de l'efficacité de la consommation de temps de huit algorithmes de tri courants en Python. Je le partage avec vous pour votre référence. Les détails sont les suivants :

Hier soir, j'ai commencé à résumer plusieurs algorithmes de tri courants. Depuis que j'ai déjà écrit plusieurs articles de blog sur les algorithmes de tri, je peux le résumer maintenant. . Il est très pratique de dire que le but ici est de résumer ces algorithmes de tri plus complètement et en détail, afin de passer en revue les éléments de base, du tri à bulles, du tri par insertion directe, du tri par sélection, du tri par fusion, du tri Hill, du tri par bucket. , tri en tas Trier. Commençons par un tri rapide à analyser et à mettre en œuvre. À la fin, nous donnons également des statistiques de temps simples. L'accent est mis sur les principes et les fondements de l'algorithme, suivis par d'autres. La maîtrise de ces éléments n'est pas importante pour les travaux futurs ou la préparation aux entretiens. Très utile. L'algorithme se concentre sur la compréhension du sens intérieur et de la base théorique. Ce n'est qu'en le mettant en œuvre que vous pourrez éviter les pièges et faire moins d'erreurs. Cela ne signifie pas qu'il est mauvais de faire des erreurs pendant la pratique, mais cela signifie qu'il devrait y en avoir. Quelques erreurs possibles qui ne devraient pas se produire. Bien joué. Après tout, de bonnes habitudes de programmation sont indissociables de contraintes strictes. Eh bien, je n'entrerai pas dans les détails ici. Passons en revue les connaissances de base et étudions ensemble. . Les commentaires doivent être très détaillés :

#!usr/bin/env python
#encoding:utf-8
'''''
__Author__:沂水寒城
功能:八大排序算法
'''
import time
import random
time_dict={}
def time_deco(sort_func):
  '''''
  时间计算的装饰器函数,可用于计算函数执行时间
  '''
  def wrapper(num_list):
    start_time=time.time()
    res=sort_func(num_list)
    end_time=time.time()
    time_dict[str(sort_func)]=(end_time-start_time)*1000
    print '耗时为:',(end_time-start_time)*1000
    print '结果为:', res
  return wrapper
def random_nums_generator(max_value=1000, total_nums=20):
  '''''
  随机数列表生成器
  一些常用函数:
  random随机数生成
  random.random()用于生成一个0到1之间的随机数:0 <= n < 1.0;
  random.uniform(a, b),用于生成一个指定范围内的随机符点数,两个参数其中一个是上限,一个是下限。min(a,b) <= n <= max(a,b);
  randdom.randint(a, b), 用于生成一个指定范围内的整数,其中a是下限,b是上限: a<= n <= b;
  random.randrange(start, stop, step), 从指定范围内,按指定基数递增的集合获取一个随机数;
  random.choice(sequence), 从序列中获取一个随机元素;
  random.shuffle(x), 用于将一个列表中的元素打乱;
  random.sample(sequence, k), 从指定序列中随机获取指定长度的片断;
  &#39;&#39;&#39;
  num_list=[]
  for i in range(total_nums):
    num_list.append(random.randint(0,max_value))
  return num_list
#@time_deco
def Bubble_sort(num_list):
  &#39;&#39;&#39;&#39;&#39;
  冒泡排序,时间复杂度O(n^2),空间复杂度O(1),是稳定排序
  &#39;&#39;&#39;
  for i in range(len(num_list)):
    for j in range(i,len(num_list)):
      if num_list[i]>num_list[j]: #这里是升序排序
        num_list[i], num_list[j]=num_list[j], num_list[i]
  return num_list
#@time_deco
def Insert_sort(num_list):
  &#39;&#39;&#39;&#39;&#39;
  直接插入排序,时间复杂度O(n^2),空间复杂度O(1),是稳定排序
  &#39;&#39;&#39;
  for i in range(len(num_list)):
    for j in range(0,i):
      if num_list[i]<num_list[j]: #这里是升序排序,跟冒泡排序差别在于,冒泡是向后遍历,这个是向前遍历
        num_list[i], num_list[j]=num_list[j], num_list[i]
  return num_list
#@time_deco
def Select_sort(num_list):
  &#39;&#39;&#39;&#39;&#39;
  选择排序,时间复杂度O(n^2),空间复杂度O(1),不是稳定排序
  &#39;&#39;&#39;
  for i in range(len(num_list)):
    min_value_index=i
    for j in range(i, len(num_list)):
      if num_list[j]<num_list[min_value_index]:
        min_value_index=j #乍一看,感觉冒泡,选择,插入都很像,选择跟冒泡的区别在于:冒泡是发现大
                 #小数目顺序不对就交换,而选择排序是一轮遍历结束后选出最小值才交换,效率更高
    num_list[i], num_list[min_value_index]=num_list[min_value_index], num_list[i]
  return num_list
#@time_deco
def Merge_sort(num_list):
  &#39;&#39;&#39;&#39;&#39;
  归并排序,时间复杂度O(nlog₂n),空间复杂度:O(1),是稳定排序
  &#39;&#39;&#39;
  if len(num_list)==1:
    return num_list
  length=len(num_list)/2
  list1=num_list[:length]
  list2=num_list[length:]
  result_list=[]
  while len(list1) and len(list2):
    if list1[0]<=list2[0]:
      result_list.append(list1[0])
      del list1[0] #这里需要删除列表中已经被加入到加过列表中的元素,否则最后比较完后列表
    else:       #中剩余元素无法添加
      result_list.append(list2[0])
      del list1[0]
  if len(list1): #遍历比较完毕后列表中剩余元素的添加
    result_list+=list1
  else:
    result_list+=list2
  return result_list
#@time_deco
def Shell_sort(num_list):
  &#39;&#39;&#39;&#39;&#39;
  希尔排序,时间复杂度:O(n),空间复杂度:O(n^2),不是稳定排序算法
  &#39;&#39;&#39;
  new_list = []
  for one_num in num_list:
    new_list.append(one_num)
  count=len(new_list)
  step=count/2;
  while step>0:
    i=0
    while i<count:
      j=i+step
      while j<count:
        t=new_list.pop(j)
        k=j-step
        while k>=0:
          if t>=new_list[k]:
            new_list.insert(k+1, t)
            break
          k=k-step
        if k<0:
          new_list.insert(0, t)
        #print &#39;---------本轮结果为:--------&#39;
        #print new_list
        j=j+step
        #print j
      i=i+1
      #print i
    step=step/2   #希尔排序是一个更新步长的算法
  return new_list
#@time_deco
def Tong_sort(num_list):
  &#39;&#39;&#39;&#39;&#39;
  桶排序,时间复杂度O(1),空间复杂度与最大数字有关,可以认为是O(n),典型的空间换时间的做法
  &#39;&#39;&#39;
  original_list = []
  total_num=max(num_list) #获取桶的个数
  for i in range(total_num+1): #要注意这里需要的数组元素个数总数比total_num数多一个因为下标从0开始
    original_list.append(0)
  for num in num_list:
    original_list[num] += 1
  result_list = []
  for j in range(len(original_list)):
    if original_list[j] != 0:
      for h in range(0,original_list[j]):
        result_list.append(j)
  return result_list
def Quick_sort(num_list):
  &#39;&#39;&#39;&#39;&#39;
  快速排序,时间复杂度:O(nlog₂n),空间复杂度:O(nlog₂n),不是稳定排序
  &#39;&#39;&#39;
  if len(num_list)<2:
    return num_list
  left_list = [] #存放比基准结点小的元素
  right_list = [] #存放比基准元素大的元素
  base_node = num_list.pop(0) #在这里采用pop()方法的原因就是需要移除这个基准结点,并且赋值给base_node这个变量
                #在这里不能使用del()方法,因为删除之后无法再赋值给其他变量使用,导致最终数据缺失
                #快排每轮可以确定一个元素的位置,之后递归地对两边的元素进行排序
  for one_num in num_list:
    if one_num < base_node:
      left_list.append(one_num)
    else:
      right_list.append(one_num)
  return Quick_sort(left_list) + [base_node] + Quick_sort(right_list)
def Heap_adjust(num_list, i, size):
  left_child = 2*i+1
  right_child = 2*i+2
  max_temp = i
  #print left_child, right_child, max_temp
  if left_child<size and num_list[left_child]>num_list[max_temp]:
    max_temp = left_child
  if right_child<size and num_list[right_child]>num_list[max_temp]:
    max_temp = right_child
  if max_temp != i:
    num_list[i], num_list[max_temp] = num_list[max_temp], num_list[i]
    Heap_adjust(num_list, max_temp, size) #避免调整之后以max为父节点的子树不是堆
def Create_heap(num_list, size):
  a = size/2-1
  for i in range(a, -1, -1):
    #print &#39;**********&#39;, i
    Heap_adjust(num_list, i, size)
#@time_deco
def Heap_sort(num_list):
  &#39;&#39;&#39;&#39;&#39;
  堆排序,时间复杂度:O(nlog₂n),空间复杂度:O(1),不是稳定排序
  &#39;&#39;&#39;
  size=len(num_list)
  Create_heap(num_list, size)
  i = size-1
  while i > 0:
    num_list[0], num_list[i] = num_list[i], num_list[0]
    size -= 1
    i -= 1
    Heap_adjust(num_list, 0, size)
  return num_list
if __name__ == &#39;__main__&#39;:
  num_list=random_nums_generator(max_value=100, total_nums=50)
  print &#39;Bubble_sort&#39;, Bubble_sort(num_list)
  print &#39;Insert_sort&#39;, Insert_sort(num_list)
  print &#39;Select_sort&#39;, Select_sort(num_list)
  print &#39;Merge_sort&#39;, Merge_sort(num_list)
  print &#39;Shell_sort&#39;, Shell_sort(num_list)
  print &#39;Tong_sort&#39;, Tong_sort(num_list)
  print &#39;Heap_sort&#39;, Heap_sort(num_list)
  print &#39;Quick_sort&#39;, Quick_sort(num_list)
  # print &#39;-----------------------------------------------------------------------------&#39;
  # for k,v in time_dict.items():
  #   print k, v

Les résultats sont les suivants :

Bubble_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]
Insérer_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326 , 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 900, 918, 976 , 998]
Select_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 816, 845, 885, 894, 0, 918, 954, 976, 998]
Merge_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289 , 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 813, 845, 885 , 894, 900, 918, 954, 976 , 998]
Shell_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 718, 752, 774, 3, 816, 845, 885, 894, 90 0, 918, 954, 976, 998]
Tong_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711, 717, 18, 752, 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]
Heap_sort [34, 49, 63, 67, 71, 72, 75, 120, 128, 181, 185 , 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 570, 618, 651, 701, 711 , 717, 718, 752, 774, 81 3, 816, 845, 885, 894, 900, 918, 954, 976, 998]
Tri rapide [34, 49, 63, 67, 71, 72, 75, 120 , 128, 181, 185, 191, 202, 217, 241, 257, 259, 260, 289, 293, 295, 304, 311, 326, 362, 396, 401, 419, 423, 456, 525, 618 , 651, 701, 711, 717, 718, 752 , 774, 813, 816, 845, 885, 894, 900, 918, 954, 976, 998]

Aucun décorateur n'est utilisé ici, principalement parce que je ne connais pas grand chose sur ce décorateur. Une erreur a été signalée lors du tri rapide, mais je ne l'ai pas résolue. Voici un exemple de test simple utilisant le résultat du décorateur :

.

Bubble_sort prend du temps : 0,0290870666504
Le résultat est : [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
Aucun
Insert_sort prend du temps : : 0.0209808349609
Le résultat est : [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
Aucun
Select_sort prend du temps : 0.0259876251221
Le résultat est : [ 5 , 45, 46, 63, 81, 83, 89, 89, 89, 90]
Aucun
Merge_sort prend du temps : 0,0138282775879
Le résultat est : [5, 45, 46, 63, 81, 83 , 89, 89, 89, 90]
Aucun
Shell_sort prend du temps : 0,113964080811
Le résultat est : [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
Aucun
Tong_sort prend du temps : 0,0460147857666
Le résultat est : [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
Aucun
Heap_sort prend du temps : : 0.046968460083
Le résultat est : [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
Aucun
Quick_sort [5, 45, 46, 63, 81, 83, 89, 89, 89, 90]
------------------------------------- -------- ------------------------------------
8825d39d8daff608f95b53eab980f585 0.113964080811
20f46f8ff5216da3cce608723ce26517 0.0209808349609
6c89c6b3ef98acc8b9fcdfc562bad209 0.046968460083
868916fcd40afc12ef32e347142554d8 0.0138282775879
d2b40124d4987c88c59ecf6d55c104b2 0.0460147857666
e77b7eaea8c1ba3f3a89617a951678f6 🎜>
Si j'ai le temps, je veux me renseigner sur les décorateurs, je trouve que c'est bien. pour la décoration de motifs, c'est simplement un artefact, mais il faut savoir l'utiliser et l'écrire !


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn