在路上---学习篇(一)Python 数据结构和算法 (2) -- 冒泡排序、选择排序、插入排序
独白:
第一次接触算法排序, 充满了好奇并且渴望了解其中原理,今天先学习了三种排序的方法,分别是 冒泡排序、选择排序、插入排序。学完以后发现数学知识真的很重要,越牛逼的算法要求知识越多,越精。虽说刚接触有些不容易接受,但我相信凭着不断的主动学习和练习是可以攻克的。最重要的事情 我有兴趣去学习!enjoy!
一、冒泡排序(英语: Bubble Sort):
是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
冒泡排序算法的运作如下:
- 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
-
时间复杂度
- 最优时间复杂度:O(n) (表示遍历一次发现没有任何可以交换的元素,排序结束。)
- 最坏时间复杂度:O(n2)
- 稳定性:稳定
代码:
""" 冒泡排序 时间复杂度O(n*n) 最优排序:O(n) (遍历一次没发现任何可以交换的元素) 稳定性 : 稳定 """ import time import random def new_num(lis): """随机生成50个数加入列表中""" for i in range(50): j = random.randint(0,100000) lis.append(j) # 开始时间 first_time = time.time() def bubble_sort_high(list1): """升序排列""" for j in range(len(list1)-1,0,-1): for i in range(j): if list1[i] > list1[i+1]: # 区别 list1[i],list1[i+1] = list1[i+1],list1[i] def bubble_sort_low(list2): """降序排列""" for j in range(len(list2)-1,0,-1): for i in range(j): if list2[i] < list2[i+1]: # 区别 list2[i],list2[i+1] = list2[i+1],list2[i] # 空列表 lis = [] # 随机函数添加到列表中 new_num(lis) # 列表排序 bubble_sort_high(lis) print(lis) # 结束时间 last_time = time.time() print("共用时%s" % (last_time - first_time))
二、选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换。在所有的完全依靠交换去移动元素的排序方法中,选择排序属于非常好的一种。
时间复杂度
- 最优时间复杂度:O(n2)
- 最坏时间复杂度:O(n2)
- 稳定性:不稳定(考虑升序每次选择最大的情况)
代码
""" 选择排序 最优时间复杂度:O(n*n) 不稳定 """ import random import time def selection_sort_high(list): """ 升序排列 """ # n 等于列表长度 n = len(list) # 需要n-1次循环 选择操作 for j in range(n-1): # 选出最小下标 min_index = j # 从当前位置 与 其下标后边元素进行比较 选出最小数据 for i in range(j+1,n): if list[i] < list[min_index]: min_index = i # 如果选择出的数据不正确,进行交换 if min_index != j: list[j], list[min_index] = list[min_index],list[j] def selection_sort_low(list): """ 降序排列 """ n = len(list) for j in range(n-1): max_index = j for i in range(j+1,n): if list[i] > list[max_index]: max_index = i list[j],list[max_index] = list[max_index], list[j] def freestyle(list): """另一种表达式""" n = len(list) for j in range(n-1,0,-1): max_index = j for i in range(j): if list[i] > list[max_index]: max_index = i list[j], list[max_index] = list[max_index],list[j] def new_num(lis): """随机生成50个数加入列表中""" for i in range(50): j = random.randint(0,10000) lis.append(j) first_time = time.time() # 空列表 lis = [] # 随机函数添加到列表中 new_num(lis) # 列表排序 selection_sort_high(lis) print(lis) # 结束时间 last_time = time.time() print("共用时%s" % (last_time - first_time))
三、插入排序
插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间
时间复杂度
- 最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
- 最坏时间复杂度:O(n2)
- 稳定性:稳定
代码:
""" 插入排序 时间复杂度:O(n*n) 稳定性:稳定 """ import random import time def insert_sort(list): n = len(list) # 从第二个位置 开始插入 即下标为1 for j in range(1,n): # 从第j个元素开始比较 如果小于前一个元素,则交换位置 for i in range(j,0,-1): if list[i] < list[i-1]: list[i],list[i-1] = list[i-1],list[i] def new_num(lis): """随机生成50个数加入列表中""" for i in range(50): j = random.randint(0,10000) lis.append(j) first_time = time.time() # 空列表 lis = [] # 随机函数添加到列表中 new_num(lis) # 列表排序 insert_sort(lis) print(lis) # 结束时间 last_time = time.time() print("共用时%s" % (last_time - first_time))