代码这里仅供参考。写法不唯一
如果错误,请在下方评论,我看到后立即修正

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)

SyntaxError
199 声望19 粉丝