常用的排序和查找算法实现
1.冒泡排序
思路:
- 1取出数组中的第一个元素,和其他元素比较,把大的交换到后一位,直到找出数组中最大的元素放到末尾;
- 2.重复以上步骤,直到找出第二大,第三大的元素,直到最小的元素;
def bubble_sort(nums):
# 注意边界条件
if len(nums) < 2:
return nums
#第一层遍历,表示遍历次数
for i in range(len(nums)):
# 第二次遍历,将前一个元素和后一个比较;注意两两比较的次数比数组的长度要小一次,所以要减一
for j in range(len(nums)-i-1):
# 把大的交换到后面位置
if nums[j] > nums[j+1]:
nums[j], nums[j+1] = nums[j+1], nums[j]
return nums
2.快速排序
思路:
- 1.取出一个中间元素(一般为第一个元素),将数组中的元素分为左右两个数组;
- 2.将左右两个子数组分别再递归调用,直到左右两个子数组的长度为1;
- 3.返回合并后的数组;
def qucik_sort(nums):
# 递归终止条件
if len(nums) < 2:
return nums
# 取中间元素
mid = nums[0]
# 将数组分为左右两个子数组,通过列表推导式(注意等号不能忘)
left_nums = [i for i in nums[1:] if i <= mid]
right_nums = [j for j in nums[1:] if j > mid]
# 返回合并后的数组
return quick_sort(left_nums) + [mid] + quick_sort(right_nums)
3.归并排序
思路:
- 1.取一个中间数,将数组分为左右两个数组
- 2.将拆分后的左右数组再递归的拆分,直到数组的长度为1
- 3.将拆分到数组长度为1的左右两个有序数组合并为一个有序数组
合并两个数组的代码如下:
# 合并两个有序数组
def merge_sort(l1:list, l2:list)->list:
if l1 is None and l2 is None:
return []
l = []
i = 0
j = 0
while i < len(l1) and j < len(l2):
# 等于号放两边都可以
if l1[i] <= l2[j]:
l.append(l1[i])
i += 1
else:
l.append(l2[j])
j += 1
# 将剩余的数也添加到数组中
l.extend(l1[i:]) if i < len(l1) else l.extend(l2[j:])
return l
归并排序的代码如下:
def gui_sort(nums:list)->list:
if len(nums) < 2:
return nums
# 取中间值进行拆分数组
mid = int(len(nums)/2)
# 将拆分后的数组进行递归调用,直到返回两个有序的数组
left_nums = gui_sort(nums[:mid])
right_nums = gui_sort(nums[mid:])
return merge_sort(left_nums, right_nums)
4.堆排序
思路:
- 通过heapq模块中的方法将要排序的数组中的元素构成最小堆
- 再将最小堆中元素pop出来即可(每次pop出来的是最小的元素即数的根节点值)
代码如下:
'''通过heapq模块实现堆排序'''
from heapq import heappush, heappop
def heap_sort(li):
item = []
for value in li:
# 将数组中元素通过heappush方法添加到空列表中构建最小堆结构
heappush(item, value)
# 再将item中的元素pop出来即为排序后的数组
return [heappop(item) for i in range(len(item))]
li = [1,4,5,6,3,9]
print(heap_sort(li))
5.二分查找
思路:
- 每次取有序数组中的中间元素,将要查找的元素和中间元素比较,根据比较结果来缩小查找范围直到找出目标元素或未查找到返回
代码如下:
# 二分查找
def two_find(target:int, nums:list)->int:
if len(nums) == 0:
return -1
left = 0
right = len(nums)-1
while left <= right:
# 获取中间元素的索引
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid -1
return -1
print(two_find(3, [1, 3, 5, 7, 8, 9, 12, 20]))