排序算法

排序算法是常练常新

选择

选择排序
# 1. 将索引位置 0 定义为最小的值 min_idx
# 2. 遍历数组,找到数组中最小的值
# 3. 在遍历的时候,如果找到任何小于 min_idx 的元素,则交换两个值
# 4. 移动 min_idx 指针
# 5. 重复上述动作直到数组排序完成

test_list = [64, 25, 12, 22, 11]
print(test_list)


def select_sort(arr):
    for i in range(len(arr) - 1):
        min_idx = i
        for j in range(i + 1, len(arr)):
            if arr[min_idx] > arr[j]:
                min_idx = j
        arr[i], arr[min_idx] = arr[min_idx], arr[i]

    return arr


select_sort(arr=test_list)

print(test_list)

冒泡

冒泡排序
# 1. 通过两个变量,i 和 j,跑两个嵌套循环遍历数组
# 2. if arr[i] > arr[j] 交换相邻元素


def bubble_sort(arr):
    for i in range(1, len(arr)):
        for j in range(0, len(arr) - i):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr


result = bubble_sort([3, 5, 1, 6, 9, 2, 4, 7])
print(result)

插入

插入
# 1. 循环遍历数组 arr
# 2. 比较当前元素和其前身
# 3. 如果当前元素小于其前身,则将其与之前的元素进行比较。将较大的元素向后移动一个位置


def insert_sort(arr):
    for i in range(len(arr)):
        cur = arr[i]  # 指定当前元素
        j = i - 1
        # 当前元素和其前身比较
        while j >= 0 and arr[j] > cur:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = cur
    return arr


result = insert_sort([2, 5, 1, 7, 8, 3, 4, 6])
print(result)

147. 对链表进行插入排序open in new window

147. 对链表进行插入排序
# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next


class Solution:
    def insertionSortList(self, head: ListNode) -> ListNode:
        if not head:
            return head

        dummy = ListNode(0)
        dummy.next = head
        last_sorted = head
        cur = head.next
        while cur:
            if last_sorted.val <= cur.val:
                last_sorted = last_sorted.next
            else:
                prev = dummy
                while prev.next.val <= cur.val:
                    prev = prev.next
                last_sorted.next = cur.next
                cur.next = prev.next
                prev.next = cur
            cur = last_sorted.next
        return dummy.next

归并

分治的思路

归并
def merge(left, right):
    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0))
    return result


def merge_sort(arr):
    if len(arr) < 2:
        return arr
    mid = 0 + ((len(arr) - 0) >> 1)
    left = arr[:mid]
    right = arr[mid:]
    return merge(merge_sort(left), merge_sort(right))


xxx = merge_sort([9, 10, 2, 8, 7, 100, 22, 99, 15])
print(xxx)

快排

和归并一样,也是分治的思路

快排
def partition(arr, low, high):
    # 总是选择最右的
    pi = arr[high]
    i = low - 1
    for j in range(low, high):
        if arr[j] <= pi:
            i += 1
            arr[i], arr[j] = arr[j], arr[i]

    arr[i + 1], arr[high] = arr[high], arr[i + 1]
    return i + 1


def quick_sort(arr, low, high):
    if low < high:
        pi = partition(arr, low, high)
        quick_sort(arr, low, pi - 1)
        quick_sort(arr, pi + 1, high)


arr = [0, 5, 1, 8, 7, 9]
quick_sort(arr, 0, len(arr) - 1)
print(arr)

堆排

大根堆:每个节点的值都大于或等于其子节点的值

小根堆:每个节点的值都小于或等于其子节点的值

堆排
def heapify(arr, n, i):
    left = 2 * i + 1
    right = 2 * i + 2
    largest = i

    if left < n and arr[left] > arr[largest]:
        largest = left
    if right < n and arr[right] > arr[largest]:
        largest = right
    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)


def heap_sort(arr):
    n = len(arr)
    # 构建大根堆
    for i in range(n // 2, -1, -1):
        heapify(arr, n, i)

    for i in range(n - 1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)


arr = [10, 7, 8, 1, 5, 3, 2, 7, 6]
heap_sort(arr)
print(arr)
上次更新:
贡献者: kongzZ