Python实现 《算法导论 第三版》中的算法 第2章 算法基础

目录

    • 第2章 算法基础
      • 1. 插入排序
      • 2. 归并排序
      • 3. 选择排序
      • 4. 冒泡排序
      • 5. 我喜欢的归并排序写法

第2章 算法基础

1. 插入排序

P10。插入排序比较简单。

class InsertionSort:
    def sort(self, A):
        for i in range(1, len(A)):
            temp = A[i]
            j = i - 1
            while j >= 0 and A[j] > temp:
                A[j + 1] = A[j]
                j -= 1
            A[j + 1] = temp # 不满条件的下一个位置


def main():
    isort = InsertionSort()
    A = [5, 2, 4, 6, 1, 3] # P10例子
    isort.sort(A)
    print(A)

  
if __name__ == '__main__':
    main()

2. 归并排序

P17。归并排序利用了分治法。

class MergeSort:
    def _merge(self, A, p, q, r):
        import math
        n1 = q - p + 1
        n2 = r - q
        L = [0] * (n1 + 1)
        R = [0] * (n2 + 1)
        for i in range(n1):
            L[i] = A[p + i]
        for j in range(n2):
            R[j] = A[q + j + 1]
        L[n1] = math.inf
        R[n2] = math.inf
        i = j = 0
        for k in range(p, r+1):
            if L[i] <= R[j]:
                A[k] = L[i]
                i += 1
            else:
                A[k] = R[j]
                j += 1
                
    def sort(self, A, p, r):
        if p < r:
            q = (p + r) // 2
            self.sort1(A, p, q)
            self.sort1(A, q+1, r)
            self._merge(A, p, q, r)          

    
def main():
    ms = MergeSort()
    A = [2, 4, 5, 7, 1, 2, 3, 6] # P18例子
    ms.sort1(A, 0, 7)
    print(A)
    
    
if __name__ == '__main__':
    main()

归并排序的其他写法。该写法与书中的伪代码不一样,因为使用了不同的参数。

class MergeSort:
    def _merge(self, arr1, arr2):
        res = []
        i1 = i2 = 0
        while i1 < len(arr1) and i2 < len(arr2):
            if arr1[i1] < arr2[i2]:
                res.append(arr1[i1])
                i1 += 1
            else:
                res.append(arr2[i2])
                i2 += 1
               
        if i1 == len(arr1):
            res.extend(arr2[i2:])
        else:
            res.extend(arr1[i1:])
            
        return res
        
    def sort(self, arr):
        if len(arr) <= 1:
            return arr
        mid = len(arr) // 2
        left_arr = self.sort(arr[:mid])
        right_arr = self.sort(arr[mid:])
        return self._merge(left_arr, right_arr)


def main():
    A = [2, 4, 5, 7, 1, 2, 3, 6] # P18例子
    print(ms.sort(A))
    
    
if __name__ == '__main__':
    main()

3. 选择排序

P16练习2.2-2。

class SelectionSort:
    def sort(self, A):
        for i in range(0, len(A)):
            k = i
            # Find the smallest num and record its index
            for j in range(k, len(A)):
                if A[j] < A[k]:
                    k = j
            if k != i:
                A[i], A[k] = A[k], A[i]
    
    
def main():
    ss = SelectionSort()
    A = [5, 2, 4, 6, 1, 3] # P10例子
    ss.sort(A)
    print(A)
    
    
if __name__ == '__main__':
    main()

4. 冒泡排序

P23思考题2-2。

class BubbleSort:
    def sort(self, A):
        for i in range(len(A)):
            for j in range(0, len(A)-i-1):
                if A[j] > A[j+1]:
                    A[j], A[j+1] = A[j+1], A[j]
                    
    
def main():
    bs = BubbleSort()
    A = [5, 2, 4, 6, 1, 3] # P10例子
    bs.sort(A)
    print(A)

  
if __name__ == '__main__':
    main()     

5. 我喜欢的归并排序写法

def merge(A, left, mid, right):
    """A[left:mid+1], A[mid+1:right+1]"""
    container = []  # 用于存储有序数字
    i, j = left, mid + 1
    while i <= mid and j <= right:
        if A[i] <= A[j]:
            container.append(A[i])
            i += 1
        else:
            container.append(A[j])
            j += 1
    container.extend(A[i: mid + 1])
    container.extend(A[j: right + 1])
    A[left: right + 1] = container


def merge_sort(A, left, right):
    if left < right:
        mid = left + (right - left) // 2
        merge_sort(A, left, mid)
        merge_sort(A, mid + 1, right)
        merge(A, left, mid, right)


if __name__ == '__main__':
    A = [0, 1, 2, 3, 4, 9, 8, 7, 4, 4]
    merge_sort(A, 0, len(A)-1)
    print(A)

你可能感兴趣的:(默认,Python,算法)