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)

    7. 桶排序:
    原理:找到一组数中最大的数据创造一个长度是最大数据的列表加1(包括0),遍历排序数组,每个数据被当作角标,用全是0 的列表记录每个数据出现的次数,最后输出,出现几次输出几次。

    时间复仇度:O(M+N)

     1 list1 = [5, 56, 8, 9, 5, 42, 4, 6, 4]
     2 
     4 def sortd(list):
     5     # 准备一个桶
     6     list_bucket = [0] * (max(list) + 1)
     7     list_result = []
     8     for i in list:
     9         list_bucket[i] += 1
    10 
    11     for i in range(len(list_bucket)):
    12         if list_bucket[i] != 0:
    13             for j in range(list_bucket[i]):
    14                 list_result.append(i)
    15     return list_result
    16 
    17 
    18 if __name__ == "__main__":
    19   
    20     print(sortd(list1))
  • 相关阅读:
    Knockout应用开发指南 第八章:简单应用举例(2)
    微软ASP.NET站点部署指南(7):生产环境部署
    Knockout应用开发指南 第七章:Mapping插件
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(6)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(5)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(3)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(9)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(8)
    Microsoft Visual Studio .NET 2003 引导程序插件下载地址(非官方)
    Vs2010在没有安装SQL Server 2005/2008 Express时如何连接MDF数据文件?
  • 原文地址:https://www.cnblogs.com/cwp-bg/p/7476296.html
Copyright © 2011-2022 走看看