排序算法
冒泡排序
冒泡排序(Bubble Sort)一种交换排序,它的基本思想是:两两比较相邻记录的
关键字,如果反序则交换,直到没有反序的记录为止。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。
冒泡排序算法的运作如下:
- 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
这步做完后,最后的元素会是最大的数。 - 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
- 最好的情况,也就是要排序的表本身就是有序的,那么我们比较次数,可以推断出就是n‐1 次的比较,没有数据交换,时间复杂度为O(n)。
- 最坏的情况,即待排序表是逆序的情况,此时需要比较1+2+3+4+…+(n-1)=n(n-1)/2次,即时间复杂度为O(n**2)。
- 稳定性: 稳定
快速排序
快速排序(Quick Sort)的基本思想是:通过一趟排序将待排记录分割成独立的
两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部
分记录继续进行排序,以达到整个序列有序的目的。
层数为O(logn)(即调用栈的高度为O(logn)),而每层需要的时间为O(n)。因此整个算法需要的时间为O(n) * O(logn) = O(nlogn)
插入排序
直接插入排序
直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增 1 的有序表。
原理:
每次将排序中的元素,插入到前面已经排好序的有序序列中去,直到排序完成。
步骤:
第一步,a[0]为有序区,待排序区为a[1…n-1]。令i=1。
第二步,将a[1]与a[0]中元素比较,将小的元素放在第一个位置。
第三步,以此类推,直到待排序中全部元素插入完成为止。
时间复杂度:
最好的情况,也就是要排序的表本身就是有序的, 因此没有移动的记录,时间复杂度为 O(n)。
最坏的情况,即待排序表是逆序的情况,时间复杂度为 O(n**2)。
希尔排序
希尔排序是D.L.Shell于 1959 年提出来的一种排序算法,在这之前排序算法的时间复杂度基本
都是O(n2)的,希尔排序算法是突破这个时间复杂度的第一批算法之一。
基本思想:
算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的然后
再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行
直接插入排序后,排序完成。
一般在记录的数量多的情况下,希尔排序的排序效率较直接插入排序高。
选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
最优时间复杂度:O(n2 )
最坏时间复杂度:O(n2 )
稳定性:不稳定(考虑升序每次选择最大的情况)
选择排序:堆排序
堆排序是指利用堆积树(堆)这种数据结构所设计的一种排序算法,利用数组的特点快速
定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的
值都不大于其父节点的值。最大的值一定在堆顶。
归并排序
归并排序(Merge sort),是创建在归并操作上的一种有效的排序算法。该算法是采用分治法
(Divide and Conquer)的一个非常典型的应用。
分治法:
分割:递归地把当前序列平均分割成两半。
集成:在保持元素顺序的同时将上一步得到的子序列集成到一起(归并)。
基数排序(桶排序)
基数排序(radix sort)它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog®m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。
排序算法代码
# encoding=utf-8
"""
Date:2019-07-16 09:15
User:LiYu
Email:liyu_5498@163.com
"""
class Sort(object):
# 冒泡
@staticmethod
def bubbling_sort(li):
lenght = len(li)
for i in range(0, lenght):
for j in range(0, lenght - i - 1):
if li[j] > li[j + 1]:
li[j], li[j + 1] = li[j + 1], li[j]
return li
# 快速
@staticmethod
def quick_sort(li):
if len(li) < 2:
return li
else:
piovt = li[0]
less = [i for i in li[1:] if i < piovt]
greater = [i for i in li[1:] if i >= piovt]
return Sort.quick_sort(less) + [piovt] + Sort.quick_sort(greater)
# 直接插入
@staticmethod
def insert_sort(li):
lenght = len(li)
for i in range(1, lenght):
j = i - 1
key = li[i] # li[i]要存起来,位置改变之后,同一个i索引的值会变
while j >= 0:
if key < li[j]:
li[j + 1], li[j] = li[j], key
# print(li)
j -= 1
# print()
return li
# 希尔
@staticmethod
def shell_sort(li):
lenght = len(li)
gap = int(lenght / 2)
while gap > 0:
for i in range(gap, lenght):
temp = li[i]
j = i
# 每组进行直接插入排序
while j >= gap and li[j - gap] > temp:
li[j], li[j - gap] = li[j - gap], temp
# li[j] = li[j - gap]
# j -= gap
# li[j] = temp
print(li)
gap = int(gap / 2)
return li
# 选择
@staticmethod
def selection_sort(li):
def find_smallest(li):
smallest = li[0]
smallest_index = 0
for i in range(1, len(li)):
if li[i] < smallest:
smallest = li[i]
smallest_index = i
return smallest_index
new_li = []
for i in range(len(li)):
smalless = find_smallest(li)
new_li.append(li.pop(smalless))
return new_li
# 基数
@staticmethod
def radix_sort(li):
d = len(str(max(li))) # 列表中的最大元素的位数
for i in range(d): # 0-9一共10个桶
BucketLst = [[] for k in range(10)]
for j in range(len(li)):
# 把对应位相同的数放到同一个桶中,十个桶分别是BucketLst[0]~BucketLst[9]
BucketLst[li[j] // (10 ** i) % 10].append(li[j]) # 10**i是关注点,之前一直是10**d,debug才发现
# 每一位排序完成后更新一次,d次之后就是排好序的新列表
li = [number for B in BucketLst for number in B] # 关键2-依次拿出桶中的元素,给原列表Lst,
# 而不是给缓存 temp = [number for B in BucketLst for number in B]
return li
if __name__ == '__main__':
li = list(input())
S = Sort()
print(li)
# print(S.bubbling_sort(li))
# print(S.quick_sort(li))
# print(S.insert_sort(li))
# print(S.shell_sort(li))
# print(S.selection_sort(li))
# li = [4, 3, 1, 1]
# print(S.radix_sort(li))
标签:sort,排序,元素,gap,算法,li,数据结构 来源: https://blog.csdn.net/Dreaming5498/article/details/96180448
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。