8个常用排序算法 之 python实现

来源:互联网 发布:内部链接优化注意问题 编辑:程序博客网 时间:2024/06/04 05:17
1、冒泡

#!/usr/bin/env
# coding:utf-8
# 排序算法之冒泡排序(1. 稳定排序)
# 2. 时间复杂度为 o(n, n^2)
# 3. 基本思想是:
#     两两比较相邻元素,如果反序则交换,直到没有反序的记录为止
# 4. 适用:n较小
  1. class Solution:
  2.     def bubble(self, alist):
  3.         #
  4.         L = len(alist)
  5.         for i in range(L):
  6.             for j in range(i+1, L):
  7.                 if alist[i] > alist[j]:
  8.                     alist[i], alist[j] = alist[j], alist[i]
  9.         return  alist
  10.            
  11. alist = [41, 26, 3, 17, 62, 31, 44, 55, 20]
  12. a = Solution()
  13. print a.bubble(alist)


2、选择排序

#!/usr/bin/env
# coding:utf-8
# 直接选择排序(递减增量排序算法)(1. 不稳定排序)
# 2. 时间复杂度为O(n^2).
# 3. 基本思想是:
#     首先在所有记录中选出序码最小的记录,把它与第1个记录交换,
#     然后在其余的记录内选出排序码最小的记录,与第2个记录交换......依次类推,直到所有记录排完为止
# 4. 适用:n较小
  1. class Solution:
  2.     # 直接选择排序
  3.     def Select_Sort(self, alist):
  4.         # 选择排序
  5.         count = len(alist)
  6.         for i in range(0, count):
  7.             min = i
  8.             for j in range(i + 1, count):
  9.                 if alist[min] > alist[j]:
  10.                     min = j
  11.             alist[min], alist[i] = alist[i], alist[min]
  12.         return alist
  13. alist = [41, 26, 3, 17, 62, 31, 44, 55, 20]
  14. a = Solution()
  15. print a.Select_Sort(alist)


3、希尔排序

#!/usr/bin/env
# coding:utf-8
# 希尔(Shell)排序(递减增量排序算法)(1. 不稳定排序)
# 2. 希尔排序的执行时间依赖于增量序列,其平均时间复杂度为O(n^(3/2)),下界为n*log2n.
# 3. 基本思想是:
#     先取一个小于n的整数d1作为第一个增量把文件的全部记录分成d1个组。
#     所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;
#     然后,取得第二个增量d2<d1重复上述的分组和排序,直至所取的增量di=1,即所有记录放在同一组中进行直 接 #     插入排序为止。
#    该方法实质上是一种分组插入方法。
# 4. 适用:n较小

# 一般取d1=n/2,di+1=di/2。如果结果为偶数,则加1,保证di为奇数。
#
  1. class Solution:
  2.     # 插入排序
  3.     def Shell(self, alist):
  4.         # 设定步长
  5.         step = len(alist)/2
  6.         while step > 0:
  7.             for i in range(step, len(alist)):
  8.                 # 类似插入排序, 当前值与指定步长之前的值比较, 符合条件则交换位置
  9.                 while i >= step and alist[i-step] > alist[i]:
  10.                     alist[i], alist[i-step] = alist[i-step], alist[i]
  11.                     i -= step
  12.             step = step/2
  13.         
  14.         return alist
  15.             
  16. alist = [41, 26, 3, 17, 62, 31, 44, 55, 20]
  17. a = Solution()
  18. print a.Shell(alist)



4、直接插入

#!usr/bin/env
# coding:utf-8
# 排序算法之直接插入(1. 稳定排序)
# 2. 时间复杂度为(n,  n^2)
# 3. 基本思想是:
#     每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
#     优点:(1)稳定排序
#                (2)所需辅助空间为1
#                (3)基本有序时性能比冒泡和选择要好
# 4. 适用:n较小,基本有序,结果稳定
  1. class Solution:
  2.     # 插入排序
  3.     def insert(self, alist):
  4.         # 循环查找
  5.         for index in range(1, len(alist)):
  6.             cur = alist[index]
  7.             position = index
  8.             
  9.             # 查找交换
  10.             while position > 0 and alist[position - 1] > cur:
  11.                 alist[position] = alist[position - 1]
  12.                 position -= 1
  13.             alist[position] = cur
  14.         
  15.         return alist
  16.     
  17. alist = [41, 26, 3, 17, 62, 31, 44, 55, 20]
  18. a = Solution()
  19. print a.insert(alist)
       
  
5、快排

#!/usr/bin/env
# coding:utf-8
# 排序算法之快速排序 (1. 不稳定排序)
# 2. 时间复杂度为 0(nlogn, n^2)、空间复杂度最好o(logn), 最坏为o(n),平均o(logn)
# 3. 快速排序采用了一种分治的策略,通常称其为分治法,
#     其基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这 
#     些子问题的解组合为原问题的解。
#     快速排序的具体过程如下:
#      第一步,在待排序的n个记录中任取一个记录,以该记录的排序码为准,将所有记录分成两组,
#                 第1组各记录的排序码都小于等于该排序码,第2组各记录的排序码都大于该排序码,并把该记录排在这
#     两组中间。
#      第二步,采用同样的方法,对左边的组和右边的组进行排序,直到所有记录都排到相应的位置为止。
# 4. 适用:n较大,注意递归的溢出
  1. class Solution:
  2.     def quick_sort(self, alist,low, high):
  3.         # 对序列alist[low,...high]z做快速排序
  4.         if low < high:
  5.             pivot = self.Partition(alist, low, high)
  6.             
  7.             self.quick_sort(alist, low, pivot-1)
  8.             self.quick_sort(alist, pivot+1, high)
  9.         return alist
  10.     
  11.     def Partition(self, alist, low, high):
  12.         # 取子表第一个记录作为枢轴记录
  13.         pivot_key = alist[low]
  14.         # 从表的两端交替向中间扫描
  15.         
  16.         while low < high:
  17.             # 将比枢轴小的元素交换到底端
  18.             while low < high and alist[high] >= pivot_key:
  19.                 high -= 1
  20.             alist[low], alist[high] = alist[high], alist[low]
  21.         
  22.             # 将比枢轴大的元素交换到顶端
  23.             while low < high and alist[low] <= pivot_key:
  24.                 low += 1
  25.             alist[low], alist[high] = alist[high], alist[low]
  26.         
  27.         return low
  28.     
  29. alist = [41, 26, 3, 17, 62, 31, 44, 55, 20]
  30. a = Solution()
  31. print a.quick_sort(alist, 0, len(alist)-1)


6、基数排序(桶排序)

#!/usr/bin/env
# coding:utf-8
# 排序算法之基数排序,又称桶排序(1. 稳定排序)
# 2. 时间复杂度为 0(nlog(r)m), 其中r为所采取的基数,而m为堆数
# 3. 基本思想是:
#     设单关键字的每个分量的取值范围均是C0<=Kj<=Crd-1(0<=j<=rd),
#     可能的取值个数rd称为基数.基数的选择和关键字的分解因关键字的类型而异.
#   (1).若关键字是十进制整数,则按个、十等位进行分解,基数rd=10,C0=0,C9=9,d为最长整数的位数.
#   (2).若关键字是小写的英文字符串,则rd=26,C0='a',C25='z',d为最长字符串的长度.
#   基数排序的基本思想是:从低位到高位依次对待排序的关键码进行分配和收集,经过d趟分配和收集,就可以
#        得到一个有序序列.
# 4. 适用:数据明显有几个关键字或者几个属性组成
  1. import math
  2. class Solution:
  3.     # 插入排序
  4.     def bulket_sort(self, alist, radix):
  5.         k = int(math.ceil(math.log(max(alist), radix)))
  6.         bucket = [[] for i in range(radix)]
  7.         for i in range(1, k + 1):
  8.             for j in alist:
  9.                 bucket[j / (radix ** (i - 1)) % (radix ** i)].append(j)
  10.             del alist[:]
  11.             for z in bucket:
  12.                 alist += z
  13.                 del z[:]
  14.         return alist
  15. alist = [41, 26, 3, 17, 62, 31, 44, 55, 20]
  16. a = Solution()
  17. print a.bulket_sort(alist, len(alist)+1)


7、堆排序

#!/usr/bin/env
# coding:utf-8
# 选择排序算法之堆排序(1. 不稳定)
# 2. 时间复杂度为 o(nlogn)、空间复杂度只有一个用来交换的暂存单元
#    堆排序的最坏时间复杂度为O(nlog2n), 堆排序的平均性能较接近于最坏性能,对原始序列的排序状态不敏感
# 3. 基本思路是:
#     堆排序的关键步骤有两个:
#         一 是如何建立初始堆;
#         二 是当堆的根结点与堆的最后一个结点交换后,
#              如何对少了一个结点后的结点序列做调整,使之重新成为堆。
# 4. 适用:n较大时,内存不充足
  1. class Solution:
  2.     # 堆排序
  3.     def adjust_heap(self, lists, i, size):
  4.         lchild = 2 * i + 1
  5.         rchild = 2 * i + 2
  6.         max = i
  7.         if i < size / 2:
  8.             if lchild < size and lists[lchild] > lists[max]:
  9.                 max = lchild
  10.             if rchild < size and lists[rchild] > lists[max]:
  11.                 max = rchild
  12.             if max != i:
  13.                 lists[max], lists[i] = lists[i], lists[max]
  14.                 self.adjust_heap(lists, max, size)
  15.     
  16.     def build_heap(self, lists, size):
  17.         for i in range(0, (size / 2))[::-1]:
  18.             self.adjust_heap(lists, i, size)
  19.     
  20.     def heap_sort(self, lists):
  21.         size = len(lists)
  22.         self.build_heap(lists, size)
  23.         for i in range(0, size)[::-1]:
  24.             lists[0], lists[i] = lists[i], lists[0]
  25.             self.adjust_heap(lists, 0, i)
  26. alist = [41, 26, 3, 17, 62, 31, 44, 55, 20]
  27. a = Solution()
  28. print a.Heap_Sort(alist)


8、计数排序

#!/usr/bin/env
# coding:utf-8
# 排序算法之计数排序 (1.稳定排序)
# 2. 时间复杂度为 O(n+k)
# 3. 假设前提:n个输入元素中的每一个都是在0到k区间内的一个整数,其中k为某个整数
#    基本思想是:
#     对每一个输入元素x,确定小于x的元素个数。利用这一信息,就可以直接把x放到它
#     输出数组中的位置上了。例如:如果有17个元素小于x,则x就应该放在第18个输出位置上。
#     当有几个元素相同时,这一方案要略作修改。
# 4. 适用:出现次数排序
  1. class Solution:
  2.     # 插入排序
  3.     def Count_sort(self, alist):
  4.         n = len(alist)
  5.         blist = [None] * n
  6.         for i in range(n):
  7.             p = 0
  8.             q = 0
  9.             for j in range(n):
  10.                 if alist[j] < alist[i]:
  11.                     p += 1
  12.                 elif alist[j] == alist[i]:
  13.                     q += 1
  14.             for k in range(p, p + q):
  15.                 blist[k] = alist[i]
  16.                 
  17.         return blist
  18. alist = [41, 26, 3, 17, 62, 31, 44, 55, 20]
  19. a = Solution()
  20. print a.Count_sort(alist)


原创粉丝点击