当前位置:   article > 正文

数据结构与算法Python——Lesson5

数据结构与算法Python——Lesson5

希尔排序

希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。

基本步骤:将数组列在一个表中并对列分别进行插入排序,重复这过程,不过每次用更长的列(步长更长了,列数更少了)来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序。

  1. def shell_sort(alist):
  2. n =len(alist)
  3. # 初始步长
  4. gap = n // 2
  5. while gap > 0:
  6. # 按步长进行插入排序
  7. for i in range(gap, n):
  8. j = i
  9. # 插入排序
  10. while j>=gap and alist[j-gap] > alist[j]:
  11. alist[j-gap], alist[j] = alist[j], alist[j-gap]
  12. j -= gap
  13. # 得到新的步长
  14. gap = gap // 2
  15. alist = [54,26,93,17,77,31,44,55,20]
  16. shell_sort(alist)
  17. print(alist)

时间复杂度

  • 最优时间复杂度:根据步长序列的不同而不同
  • 最坏时间复杂度:O(n2)
  • 稳定想:不稳定

快速排序

快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

步骤为:

  1. 从数列中挑出一个元素,称为"基准"(pivot),
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

  1. def quick_sort(alist, start, end):
  2. """快速排序"""
  3. # 递归的退出条件
  4. if start >= end:
  5. return
  6. # 设定起始元素为要寻找位置的基准元素
  7. mid = alist[start]
  8. # low为序列左边的由左向右移动的游标
  9. low = start
  10. # high为序列右边的由右向左移动的游标
  11. high = end
  12. while low < high:
  13. # 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动
  14. while low < high and alist[high] >= mid:
  15. high -= 1
  16. # 将high指向的元素放到low的位置上
  17. alist[low] = alist[high]
  18. # 如果low与high未重合,low指向的元素比基准元素小,则low向右移动
  19. while low < high and alist[low] < mid:
  20. low += 1
  21. # 将low指向的元素放到high的位置上
  22. alist[high] = alist[low]
  23. # 退出循环后,low与high重合,此时所指位置为基准元素的正确位置
  24. # 将基准元素放到该位置
  25. alist[low] = mid
  26. # 对基准元素左边的子序列进行快速排序
  27. quick_sort(alist, start, low-1)
  28. # 对基准元素右边的子序列进行快速排序
  29. quick_sort(alist, low+1, end)
  30. alist = [54,26,93,17,77,31,44,55,20]
  31. quick_sort(alist,0,len(alist)-1)
  32. print(alist)

归并排序

归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。

将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。

  1. def merge_sort(array):
  2. if len(array) == 1:
  3. return array
  4. left_array = merge_sort(array[:len(array) // 2])
  5. right_array = merge_sort(array[len(array) // 2:])
  6. return merge(left_array, right_array)
  7. def merge(left_array, right_array):
  8. left_index, right_index, merge_array = 0, 0, list()
  9. while left_index < len(left_array) and right_index < len(right_array):
  10. if left_array[left_index] <= right_array[right_index]:
  11. merge_array.append(left_array[left_index])
  12. left_index += 1
  13. else:
  14. merge_array.append(right_array[right_index])
  15. right_index += 1
  16. merge_array = merge_array + left_array[left_index:] + right_array[right_index:]
  17. return merge_array
  18. if __name__ == '__main__':
  19. array = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
  20. print(merge_sort(array))

搜索

搜索是在一个项目集合中找到一个特定项目的算法过程。搜索通常的答案是真的或假的,因为该项目是否存在。 搜索的几种常见方法:顺序查找、二分法查找、二叉树查找、哈希查找

二分法查找

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

递归版本:

  1. def binary_search(alist, item):
  2. if len(alist) == 0:
  3. return False
  4. else:
  5. midpoint = len(alist)//2
  6. if alist[midpoint]==item:
  7. return True
  8. else:
  9. if item<alist[midpoint]:
  10. return binary_search(alist[:midpoint],item)
  11. else:
  12. return binary_search(alist[midpoint+1:],item)
  13. testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
  14. print(binary_search(testlist, 3))
  15. print(binary_search(testlist, 13))

非递归版本:

  1. def binary_search(alist, item):
  2. first = 0
  3. last = len(alist) - 1
  4. while first <= last:
  5. midpoint = (first + last) // 2
  6. if alist[midpoint] == item:
  7. return True
  8. elif item < alist[midpoint]:
  9. last = midpoint - 1
  10. else:
  11. first = midpoint + 1
  12. return False
  13. testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42, ]
  14. print(binary_search(testlist, 3))
  15. print(binary_search(testlist, 13))

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/466159
推荐阅读
相关标签
  

闽ICP备14008679号