python递归实现二分查找_常见排序算法与二分查找(Python实现)

代码这里仅供参考。写法不唯一

如果错误,请在下方评论,我看到后立即修正

1.冒泡排序

冒泡排序即每次比较相邻的两元素,如果前面比后面大,就替换位置。从头到尾遍历完一轮后,至少会选出最大的那个元素排到末尾。然后再这样循环n-1次。

代码需要两层循环,外层循环代表需要遍历的次数,内存循环代表每次遍历需要两两比对的次数。def bubble_sort(list_2):

n = len(list_2)

"""从头到尾走的次数为n-1"""

for j in range(n-1):

"""每次走需要判断的次数为n-1"""

for i in range(n-1-j):

if list_2[i] > list_2[i+1]:

list_2[i+1], list_2[i] = list_2[i], list_2[i+1]

return list_2

test_list = [1, 10, 44, 23, 43, 33, 89, 20, 90, 27, 23, 13, 45, 92, 67, 71]

print(bubble_sort(test_list))

2.选择排序

选择排序即每次默认最靠前的那个元素为最小的,遍历一轮,如果还有比它小的,就互换位置。遍历完一轮后,至少会选出最小的那个元素。下次遍历从最小元素的下一个元素开始遍历。def select_sort(test_list):

n = len(test_list)

for j in range(n-1):

"""每次遍历中,比较的次数会减小,所以用range(n-1-j)"""

for i in range(n-1-j):

"""test_list[i+1+j]每次遍历时,比较的第一个数的索引会越来越大"""

if test_list[i+1+j] < test_list[j]:

test_list[j], test_list[i+1+j] = test_list[i+1+j], test_list[j]

return test_list

test_list = [19, 1, 10, 44, 23, 43, 33, 89, 20, 90, 27, 23, 13, 45, 92, 67, 71]

print(select_sort(test_list))

3.插入排序

插入排序与选择排序可以比较着理解。选择排序是后面的数列排序。插入排序是对前面的数列排序。

插入排序,即直接将最靠前的元素往前面的有序数列插,插入之后,再排序。def insert_sort(test_list):

n = len(test_list)

for j in range(n-1):

"""每次遍历,需要比较的次数是逐渐增大的"""

for i in range(1+j):

if test_list[j+1-i] < test_list[j-i]:

"""注意在比较的过程中,索引值是一直变化的"""

test_list[j+1-i], test_list[j-i] = test_list[j-i], test_list[j+1-i]

else:

"""比当前值小的不再比较,直接跳出本次循环"""

break

return test_list

test_list = [1, 10, 44, 23, 43, 33, 89, 20, 90, 27, 23, 13, 45, 92, 67, 71]

print(insert_sort(test_list))

4.希尔排序

希尔排序实际是分组的插入排序。# 第一组有可能为3个元素,此时,可以将第一组的比较再分为两组,即1与2比较,2与3比较。

# 将2与3的比较放在最后比较,然后最终所有组就可以都化成只有两个元素比较

# 比较的次数为(n-gap-1),起始是gap,结束是n-1,所以range范围为(gap,n-1)

def shell_sort(test_list):

"""取递减的步长,进行插入排序"""

n = len(test_list)

"""地板除法,取到步长gap"""

gap = n//2

while gap > 0:

"""对每组的元素进行插入排序"""

for j in range(gap, n):

"""对一组内的元素进行插入排序"""

while j > 0:

if test_list[j] < test_list[j-gap]:

test_list[j], test_list[j-gap] = test_list[j-gap], test_list[j]

j -= gap

else:

break

"""重新进行分组,直到步长为1"""

gap = gap//2

return test_list

5.快速排序(面试常问)

快速排序即从默认第一个数为中数,然后从数列两端向中间遍历。一轮过后,中数左边的数都比中数小,中数右边的数都比中数大。然后再分别遍历左右两个数列。def quick_sort(test_list, first, last):

"""递归终止条件,为什么用>=,因为low-1有可能比first小"""

if first >= last:

return

low = first

high = last

mid_value = test_list[first]

while low < high:

while low < high and test_list[high] >= mid_value:

high -= 1

test_list[low] = test_list[high]

while low < high and test_list[low] < mid_value:

low += 1

test_list[high] = test_list[low]

"""两指针相遇时,low==high,所有将中间值赋值给low即可"""

test_list[low] = mid_value

quick_sort(test_list, first, low-1)

quick_sort(test_list, low+1, last)

test_list = [19, 1, 10, 44, 23, 43, 33, 89, 20, 90, 27, 23, 13, 45, 92, 67, 71]

quick_sort(test_list, 0, len(test_list)-1)

print(test_list)

6.归并排序(面试常问)

归并排序与快速排序都用到了递归与分治的思想。

归并排序首先将数列分隔成直至不能分割的单独的数为止,然后再往上两两有序合并,合并的过程就是合并两个有序数组的过程。def merge_sort(test_list):

"""分而治之,需要left与right两个指针,与快排类似"""

n = len(test_list)

if n <= 1:

return test_list

mid = n//2

left_list = merge_sort(test_list[:mid])

right_list = merge_sort(test_list[mid:])

left_point, right_point = 0, 0

result = []

# 当中某一个指针发生越界,就跳出循环。

while left_point < len(left_list) and right_point < len(right_list):

if left_list[left_point] < right_list[right_point]:

result.append(left_list[left_point])

left_point += 1

else:

result.append(right_list[right_point])

right_point += 1

# 这里不会有问题,因为剩余的列表是最大的,有序且递增的,直接放到列表后面就行了。

result += left_list[left_point:]

result += right_list[right_point:]

return result

test_li = [1, 10, 44, 23, 43, 33, 89, 20, 90, 27, 23, 13, 45, 92, 67, 71]

print(merge_sort(test_li))

7.堆排序def heapify(unsorted, index, heap_size):

largest = index

left_index = 2 * index + 1 # 左子节点

right_index = 2 * index + 2 # 右字节点

# 如果左子节点存在,且左子节点值>根节点值,进行交换

if left_index < heap_size and unsorted[left_index] > unsorted[largest]:

largest = left_index

# 如果右子节点存在,且右子节点值》根节点值,进行交换

if right_index < heap_size and unsorted[right_index] > unsorted[largest]:

largest = right_index

# 进行了至少一次根节点与子节点的交换。递归处理其子节点。

if largest != index:

unsorted[largest], unsorted[index] = unsorted[index], unsorted[largest]

heapify(unsorted, largest, heap_size)

def heap_sort(unsorted):

# 处理为最大堆

n = len(unsorted)

for i in range(n // 2 - 1, -1, -1): # 从倒数第二层,往上处理。

heapify(unsorted, i, n)

# 将顶部节点与尾部节点交换,并重新调整为最大堆

for i in range(n - 1, 0, -1):

unsorted[0], unsorted[i] = unsorted[i], unsorted[0]

heapify(unsorted, 0, i) # 注意这里的i,即尾部依次保留堆顶弹出的节点

return unsorted

if __name__ == "__main__":

unsorted = [0, 5, 3, 2, 2, 6, 10, 4, 8]

print(heap_sort(unsorted))

# [0, 2, 2, 3, 4, 5, 6, 8, 10]

8.二分查找def binary_search(test_list, item):

low = 0

high = len(test_list) - 1

while low <= high:

guess = (low + high) // 2

if test_list[guess] == item:

print("找到了,索引值为:", guess)

return

elif test_list[guess] < item:

low = guess + 1

else:

high = guess - 1

print("未找到")

test_list = [1, 3, 5, 6, 7, 11, 14, 19, 20, 23, 26, 27, 30, 33, 34, 35, 38, 40]

binary_search(test_list, 11)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值