代码这里仅供参考。写法不唯一
如果错误,请在下方评论,我看到后立即修正
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.堆排序(前k大的数)
heap = []
def heapify(node):
# 构建最大堆
if len(heap) == 0:
heap.append(node)
return
# 首先将元素插入堆底层,然后向上冒泡
last_idx = len(heap)
heap.append(node)
father_idx = (last_idx-1) // 2 # 获取父节点idx
while father_idx>=0:
if heap[last_idx] > heap[father_idx]:
heap[last_idx], heap[father_idx] = heap[father_idx], heap[last_idx]
else:
break
last_idx = father_idx
father_idx = (last_idx-1) // 2
def heap_sort():
# 堆排
res = []
last_idx = len(heap) - 1
while heap:
# 交换首尾元素,然后弹出尾元素。然后头节点向下冒泡
heap[0], heap[last_idx] = heap[last_idx], heap[0]
res.append(heap.pop())
now_idx = 0
length = len(heap)
while 2*now_idx+1<length:
if 2*now_idx+2 <length:
if heap[now_idx] < heap[2 * now_idx + 1] and heap[2 * now_idx + 2] <= heap[2 * now_idx + 1]:
heap[now_idx], heap[2 * now_idx + 1] = heap[2 * now_idx + 1], heap[now_idx]
now_idx = 2*now_idx+1
elif heap[now_idx] < heap[2 * now_idx + 2] and heap[2 * now_idx + 1] <= heap[2 * now_idx + 2]:
heap[now_idx], heap[2 * now_idx + 2] = heap[2 * now_idx + 2], heap[now_idx]
now_idx = 2*now_idx+2
else:
break
else:
if heap[now_idx] < heap[2 * now_idx + 1]:
heap[now_idx], heap[2 * now_idx + 1] = heap[2 * now_idx + 1], heap[now_idx]
now_idx = 2*now_idx+1
else:
break
last_idx = len(heap) -1
return res
if __name__ == '__main__':
input_ = [15, 20, 11, 6, 21, 2, 3, 8, 13, 18, 35, 24, 28]
for i in input_:
heapify(i)
print(heap)
sorted_res = heap_sort()
print(sorted_res)
上面的是自己摸索手写的,非递归的,代码量很大。下面的是我在网上找的代码,然后捋了一下
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)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。