二分、冒泡、快速、插入排序

清疚 2023-10-01 08:34 64阅读 0赞

1.二分查找(折半查找)

找出**有序**数据中的中间元素,由中间元素将数据分成左右两部分,比较中间元素与待查找值的大小: 如果相等,则查找 成功; 如果中间元素比查找元素值大,则继续在左侧重复该过程; 如果中间元素比查找元素值小,则继续在右侧重复该过程; 如此递归下去,直到成功找到或者查找完所有数据为止。

使用递归实现:

  1. # -*- coding: utf-8 -*-
  2. # @Author : Codeooo
  3. # @Time : 2021/12/05
  4. # 二分查找
  5. # 使用递归实现
  6. # 原始数据 value
  7. # 待查找数据 key - 6
  8. # 当前查找范围左侧数据对应下标值 left
  9. # 当前查找范围右侧数据对应下标值 right
  10. def binary(value, key, left, right):
  11. # 递归退出条件
  12. if left > right:
  13. # 查找结束-查找失败
  14. return -1
  15. # 获取中间元素对应下标
  16. middle = (left + right) // 2
  17. # 对比中间数据值与待查找值
  18. if value[middle] == key:
  19. # 查找成功, 返回对应下标值
  20. return middle
  21. elif value[middle] > key:
  22. # 中间数据值大于待查找值时
  23. # 继续在左侧重复该过程
  24. # 查找范围缩小:左侧不变,右侧变为中间元素的前一位
  25. return binary(value, key, left, middle-1)
  26. else:
  27. # 中间数据值小于待查找值时
  28. # 继续在右侧重复该过程
  29. # 查找范围缩小:左侧变为中间元素的后一位,右侧不变
  30. return binary(value, key, middle+1, right)
  31. if __name__ == "__main__":
  32. # 原始数据 value
  33. value = [1,2,3,4,5,6,7,8,9,10,11,12,13]
  34. # 待查找数据 key
  35. key = 6
  36. # 调用二分查找
  37. res = binary(value, key, 0, len(value)-1)
  38. if res == -1:
  39. print("查找失败")
  40. else:
  41. print("查找成功:", res)

使用循环实现:

  1. # -*- coding: utf-8 -*-
  2. # @Author : Codeooo
  3. # @Time : 2021/12/05
  4. # 二分查找
  5. # 使用循环实现
  6. # 原始数据 value
  7. # 待查找数据 key - 6
  8. def binary(value, key):
  9. # 获取左侧/右侧数据对应下标值
  10. left = 0
  11. right = len(value) - 1
  12. # 如果存在合法范围则继续
  13. while left <= right:
  14. # 获取中间数据对应下标值
  15. middle = (left + right) // 2
  16. # 比较中间数据值与待查找数据
  17. if value[middle] == key:
  18. # 中间数据值与待查找数据相等
  19. # 查找成功,返回对应下标值
  20. return middle
  21. elif value[middle] > key:
  22. # 中间数据值大于待查找数据时
  23. # 继续在左侧重复查找
  24. # 查找范围缩小:左侧不变,右侧变为中间的前一位
  25. right = middle - 1
  26. else:
  27. # 中间数据值小于待查找数据时
  28. # 继续在右侧重复查找
  29. # 查找范围缩小:右侧不变,左侧变为中间的后一位
  30. left = middle + 1
  31. # 查找失败,返回-1
  32. return -1
  33. if __name__ == "__main__":
  34. # 原始数据 value
  35. value = [1,2,3,4,5,6,7,8,9,10,11,12,13]
  36. # 待查找数据 key
  37. key = 6
  38. # 调用二分查找
  39. res = binary(value, key)
  40. if res == -1:
  41. print("查找失败")
  42. else:
  43. print("查找成功:", res)

2. 冒泡排序 重复走访要排序的数据,依次对比每两个相邻的元素,如果次序错误则交换;重复进行直到没有相邻数据需要交换为止,此时完成排序

9de6676017b94a12b503d0344843bf0a.gif

  1. # -*- coding: utf-8 -*-
  2. # @Author : Codeooo
  3. # @Time : 2021/12/05
  4. # 冒泡排序
  5. # 原始数据 value
  6. def bubble(value):
  7. # 外层循环:对应数据走访的次数
  8. for i in range(len(value) - 1):
  9. # 设置初始标识为的值,为False
  10. flag = False
  11. # 内层循环:对应每次走访数据时,相邻数据对比次数
  12. for j in range(len(value) - 1 - i):
  13. # 要求从小到大,如前者大于后者,则交换
  14. if value[j] > value[j+1]:
  15. value[j],value[j+1] = value[j+1],value[j]
  16. # 若数据发生交换,则置为True
  17. flag = True
  18. # 若当前走访数据时,未发生数据交换
  19. # 则当前数据有序,无需继续走访
  20. if flag is False:
  21. break
  22. # 打印走访次数
  23. print("走访次数", i+1)
  24. if __name__ == "__main__":
  25. # 原始数据 
  26. # value = [180, 230, 149, 260, 130, 170, 160, 169, 163, 178]
  27. value = [350, 130, 149, 160, 163, 169, 170, 178, 180, 230, 260]
  28. print("原始数据:", value)
  29. # 调用排序
  30. bubble(value)
  31. print("排序后:", value)

3.插入排序

将数据插入到已经有序的部分中,从而得到新的有序数据。 默认首元素自然有序,取下一个元素对已经有序的数据从后向前扫描: 若扫描到的有序数据*大于*取出数据,则该有序数据后移; 若扫描到的有序数据*小于等于*取出数据,则在该有序数据后面插入取出数据; 若所有有序数据*均大于*取出数据,则有序数据首部插入取出数据。 重复上步骤,直到处理完所有数据为止。

c31aa91870f44460b3bfe741a04a5bbd.gif

  1. # -*- coding: utf-8 -*-
  2. # @Author : Codeooo
  3. # @Time : 2021/12/05
  4. # 插入排序
  5. # 原始数据
  6. def insert(value):
  7. # 外层循环:对应遍历所有无序数据,依次取出元素
  8. for i in range(1, len(value)):
  9. # 取出当前无序数据
  10. temp = value[i]
  11. # 存储取出数据的插入位置(下标值)
  12. pos = i
  13. # 内层循环:对应从后向前扫描所有有序数据,找出插入数据的位置
  14. # start:从最后一个有序数据开始,即无序数据前一位
  15. # end:到有序数据首位终止,包含下标为0
  16. # step:从后向前扫描:-1
  17. for j in range(i-1, -1, -1):
  18. if value[j] > temp:
  19. # 有序数据大于取出数据
  20. # 有序数据后移
  21. value[j+1] = value[j]
  22. # 更新当前取出数据可插入位置
  23. pos = j
  24. else:
  25. # 有序数据小于等于取出数据
  26. # 在有序数据后插入取出数据
  27. # 有序数据的后一位
  28. pos = j + 1
  29. # 确定插入位置,退出内层循环
  30. break
  31. # 在指定的位置插入数据
  32. value[pos] = temp
  33. if __name__ == "__main__":
  34. # 原始数据
  35. value = [99,20,85,70,30,18,100,13,76,98]
  36. print("原始数据:",value)
  37. # 调用排序
  38. insert(value)
  39. print("排序后:",value)

4.快速排序 首先任意取一个数据(通常取第一个数据)作为关键数据,然后将所有比关键数据小的放在它的前面,所有比关键数据大的放在它的后面,这样的一个过程称为一趟快速排序。 通过一趟快速排序,将所有数据分割成独立的两部分,然后按照这个方法递归对两部分数据进行快速排序,以达到所有数据有序。

11224a46205044efbacca88c99cebb7b.gif

  1. # -*- coding: utf-8 -*-
  2. # @Author : Codeooo
  3. # @Time : 2021/12/05
  4. #快速排序
  5. # 原始数据
  6. def quick(value):
  7. # 递归的退出条件
  8. # 仅有一个数据时无需继续排序
  9. if len(value) < 2:
  10. return value
  11. # 获取关键数据
  12. mark = value[0]
  13. # 找出所有比关键数据小的
  14. smaller = [x for x in value if x < mark]
  15. # 找出所有比关键数据大的
  16. bigger = [x for x in value if x > mark]
  17. # 找出所有与关键数据相等的
  18. eq = [x for x in value if x == mark]
  19. # 从小到大排序
  20. return quick(smaller) + eq + quick(bigger)
  21. if __name__ == "__main__":
  22. # 原始数据
  23. value = [88,38,77,43,18,1,100,99,96,69]
  24. print("原始数据:", value)
  25. # 调用快速排序
  26. value = quick(value)
  27. print("排序后:", value)

5.顺序查找

从待查找数据中第一元素开始,逐个对每个元素值与要查找的内容进行对比,如果相等,则查找成功;如果到最后仍未找到则查找失败。

  1. # -*- coding: utf-8 -*-
  2. # @Author : Codeooo
  3. # @Time : 2021/12/05
  4. # 顺序查找
  5. # 原始数据 value
  6. # [12, 10, 1, 3, 5, 9, 11, 6, 2, 4, 8, 7, 13]
  7. # 待查找数据 key - 7
  8. def linear(value, key):
  9. # 获取所有数据
  10. for i in range(len(value)):
  11. # 对比取出数据与待查找数据
  12. if value[i] == key:
  13. # 查找成功,返回当前下标值
  14. return i
  15. # 查找完所有数据,仍未找到
  16. # 查找失败,返回非法下标值
  17. return -1
  18. if __name__ == "__main__":
  19. # 原始数据 value
  20. value = [12, 10, 1, 3, 5, 9, 11, 6, 2, 4, 8, 7, 13]
  21. # 待查找数据 key - 7
  22. key = 7
  23. # 调用查找函数
  24. res = linear(value, key)
  25. if res == -1:
  26. # 查找失败
  27. print("查找失败")
  28. else:
  29. # 查找成功
  30. print("查找成功:", res)
  31. print((0 + 11)// 2)
  32. print((3 + 4) // 2)

发表评论

表情:
评论列表 (有 0 条评论,64人围观)

还没有评论,来说两句吧...

相关阅读