다양한 정렬 알고리즘: 퀵 정렬, 병합 정렬, 버블 정렬

1. 퀵 정렬(하향식)

1. 빠른 정렬 내부 버전

최선의 경우 시간 복잡도 : O(nlogn), 여기서 logn은 재귀 수준 수이고 n은 각 재귀 수준의 총 시간 복잡도입니다.
최악의 경우 시간 복잡도 : O(n*n)

def quicksort_inplace(left,right): #子数组第一个元素和最后一个元素在原数组中的位置
    if left >= right: #递归终止条件
        return
    l,r,std = left, right, nums[left] #初始化左指针,右指针和基准值
    while r > l:    ##调整元素位置
        while nums[r] >= std and r > l:
            r -= 1
        tmp = nums[l]
        nums[l] = nums[r]
        nums[r] = tmp
        while nums[l] < std and r > l:
            l += 1
        tmp = nums[r]
        nums[r] = nums[l]
        nums[l] = tmp
    quicksort_inplace(left,l)
    quicksort_inplace(l+1,right)
    
nums = [5,3,6,4,1,2,8,7]
quicksort_inplace(0,len(nums)-1)
print(nums)

2. 퀵 정렬 시공간 버전

최상의 경우 시간 복잡도 : O(nlogn) 미만

#快速排序
#没有if if else的用法
def quicksort_basic(arr):
    if len(arr) <= 1:
        return arr
    left = []
    right = []
    mid = []
    std = arr[len(arr) // 2]
    for x in arr:
        if x == std:
            mid.append(x)
        if x < std:
            left.append(x)
        #else:
        if x > std:
            right.append(x)
    return quicksort_basic(left) + mid + quicksort_basic(right)

2. 병합 정렬(상향식)

생각 :분열하고 정복하라. 분할 및 정복은 배열에 요소가 하나만 남을 때까지 데이터를 두 부분으로 재귀적으로 나눕니다. 병합은 두 개의 정렬된 배열을 재정렬합니다. 새로운 배열을 반환합니다. 구체적으로 병합의 의미는 다음과 같습니다. 이미 정렬된 두 개의 목록이 있다고 가정하고 , 두 목록의 시작 요소를 가리키도록 두 개의 포인터를 설정하고 , 새로운 빈 목록을 생성하기 위해 메모리 공간을 적용하고, 요소의 크기를 비교합니다. 두 포인터가 가리키는 요소. 는 더 작은 요소를 새 목록에 추가한 다음 포인터를 목록의 다음 요소로 오프셋하고 두 포인터가 가리키는 요소를 계속 비교하고 더 작은 요소를 새 목록에 추가합니다. 한 목록의 모든 데이터가 추가될 때까지 다른 목록의 나머지 데이터를 순서대로 새 목록에 추가합니다. 이는 두 개의 정렬된 목록을 새로운 정렬된 목록으로 병합하는 방법을 구현합니다.

빠른 정렬과 비교할 때 병합의 시간 복잡도는 더 안정적입니다 . O(nlogn)로 유지됩니다. 여기서 logn은 재귀 수준 수이고 n은 각 재귀 수준의 총 시간 복잡도입니다.

#归并排序
nums = [5,3,6,4,1,2,8,7]
def merge_sort(nums):
    if len(nums) <= 1:
        return nums
    left_arr = merge_sort(nums[0:len(nums) // 2])
    right_arr = merge_sort(nums[len(nums) // 2:])
    return merge(left_arr,right_arr)

def merge(left_arr,right_arr):
    rst = []
    pointer1 = 0
    pointer2 = 0
    while pointer1 < len(left_arr) and pointer2 < len(right_arr):
        if left_arr[pointer1] <= right_arr[pointer2]:
            rst.append(left_arr[pointer1])
            pointer1 += 1
        else:
            rst.append(right_arr[pointer2])
            pointer2 += 1
    return rst + right_arr[pointer2:] + left_arr[pointer1:] #技巧:right_arr[pointer2:]中加了冒号就不会报索引超出index的错误
        
rst = merge_sort(nums) 
print(rst)   

3. 버블 정렬

핵심 원리 : for 루프의 두 레이어를 사용하여 각 외부 루프는 정렬된 요소의 시작 부분에 있는 정렬되지 않은 요소의 가장 작은 요소를 배치할 수 있습니다. 최악의
시간 복잡도 : O(n*n)

#冒泡排序
nums = [5,3,6,4,1,2,8,7]
def bubbleSort(nums):
    for i in range(len(nums)):
        for j in range(i+1,len(nums)):
            if nums[j] < nums[i]:
                tmp = nums[j]
                nums[j] = nums[i]
                nums[i] = tmp      
bubbleSort(nums) 
print(nums)   

참고:
[파이썬 알고리즘 시리즈 2] 퀵 정렬 알고리즘
퀵 정렬 & 병합 정렬 - 시간 복잡도 분석
퀵 정렬과 병합 정렬
파이썬이 병합 정렬을 구현하다

추천

출처blog.csdn.net/Rolandxxx/article/details/131404824