python實現快速排序的兩種方法

代碼環境:python3.6

遞歸實現

步驟:python

  1. 從序列中挑出任意一個元素爲pivot,此處選擇序列最後一個元素,若是更改,須要相應變動如下步驟內容;
  2. 設置兩個指針leftright,指向序列的最左和最右兩個元素;
  3. left開始,找到第一個比pivot大的元素;切換到right,找到第一個比pivot小的元素;
  4. leftright此時指向的元素互換;
  5. 重複1-4步驟,直到left==right,將pivotleft對應的元素互換,這樣以pivot分割左右兩個區,左邊元素都比pivot小,右邊元素都比pivot大;
  6. 將兩個分區分別遞歸重複1-5步驟,直到不可再分區,遞歸條件就是start<end

算法實現:算法

def partition(mylist, start, end):
    pivot = mylist[end]
    left = start
    right = end

    while left < right:
        while left < right and mylist[left] <= pivot:
            left += 1
        while left < right and mylist[right] >= pivot:
            right -= 1
        if left != right:
            mylist[left], mylist[right] = mylist[right], mylist[left]

    mylist[end], mylist[left] = mylist[left], pivot
    return left


def quick_sort(mylist, start, end):
    """
    mylist: 待排序的 list
    start: mylist第一個元素索引
    end: mylist最後一個元素索引
    """
    if start < end:
        mid = partition(mylist, start, end)
        quick_sort(mylist, start, mid - 1)
        quick_sort(mylist, mid + 1, end)


if __name__ == "__main__":
    mylist = [12, 33, 199, 0, 54, 77, 11, 54, 9, 7]
    quick_sort(mylist, 0, len(mylist) - 1)
    print(f'快速排序後:{mylist}')

非遞歸實現

絕大多數用遞歸實現的問題,均可以用的方式來代替。app

爲何?由於咱們代碼中一層層的方法調用,自己就是一個函數棧,每次進入一個新方法,就至關於入棧;每次有方法返回,就至關於出棧。函數

因此,咱們能夠利用棧存儲每一次調用方法的參數。ui

算法實現:指針

class Stack():
    """簡單實現一個棧,本質就是個list"""
    def __init__(self):
        self.items = []

    def is_empty(self):
        return self.items == []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()


# 此方法與上面例子同樣,保持不變
def partition(mylist, start, end):
    pivot = mylist[end]
    left = start
    right = end

    while left < right:
        while left < right and mylist[left] <= pivot:
            left += 1
        while left < right and mylist[right] >= pivot:
            right -= 1
        if left != right:
            mylist[left], mylist[right] = mylist[right], mylist[left]

    mylist[end], mylist[left] = mylist[left], pivot
    return left


def quick_sort(mylist):
    stack = Stack()
    start = 0
    end = len(mylist) - 1

    if start < end:
        mid = partition(mylist, start, end)
        if start < mid - 1:
            stack.push((start, mid - 1))
        if mid + 1 < end:
            stack.push((mid + 1, end))
        while not stack.is_empty():
            start, end = stack.pop()
            mid = partition(mylist, start, end)
            if start < mid - 1:
                stack.push((start, mid - 1))
            if mid + 1 < end:
                stack.push((mid + 1, end))


if __name__ == "__main__":
    mylist = [12, 33, 199, 0, 54, 77, 11, 54, 9, 7]
    quick_sort_stack(mylist)
    print(f'快速排序後:{mylist}')
相關文章
相關標籤/搜索