2016-08-20 88 views
-1

最近我試圖在Python中實現quicksort算法,並且我無法使其正常工作。即使程序對子數組進行排序,它並沒有反映在主列表中。我是編程新手,所以任何人都可以幫助我理解我沒做對的部分或概念嗎?我的快速排序算法實現中的錯誤

def swap(arr, right, left): 
    temp = arr[right] 
    arr[right] = arr[left] 
    arr[left] = temp 

def split_array(arr, right): 
    left_half = arr[:right] 
    right_half = arr[right:] 
    a = (left_half, right_half) 
    return a 

def quick_sort(arr): 
    if len(arr) >= 2: 
     pivot = 0 
     left_mark = pivot + 1 
     right_mark = len(arr) - 1 
     stop = True 

     while stop: 
      while arr[pivot] > arr[left_mark] and left_mark < right_mark: 
       left_mark += 1 
      while arr[pivot] < arr[right_mark] and left_mark < right_mark: 
       right_mark -= 1 
      if left_mark < right_mark: 
       swap(arr, right_mark, left_mark) 
       right_mark -= 1 
       left_mark += 1 
      else: 
       if arr[pivot] > arr[right_mark]: 
        swap(arr, right_mark, pivot) 
       stop = False 
     left, right = split_array(arr, right_mark) 
     quick_sort(left) 
     quick_sort(right) 
    return arr 

array = [8, 6, 1, 7, 0, 5, 4, 3, 2, 1] 
print(quick_sort(array)) 

回答

2

更改此:

left, right = split_array(arr, right_mark) 
quick_sort(left) 
quick_sort(right) 

這樣:

left, right = split_array(arr, right_mark) 
arr = quick_sort(left) + quick_sort(right) 

快速排序典型地被實現「IN-放置「以避免複製數組。你的實現會在每一步創建一個完整的數組副本並返回它,所以你需要自己重新組裝這些部分。

UPDATE

一個小小的改變,使你的算法就地改爲:

def quick_sort(arr, start=0, end=None): 
    if end is None: end = len(arr)-1 
    if end > start: 
     pivot = start 
     left_mark = start + 1 
     right_mark = end 
     stop = True 

     while stop: 
      while arr[pivot] > arr[left_mark] and left_mark < right_mark: 
       left_mark += 1 
      while arr[pivot] < arr[right_mark] and left_mark < right_mark: 
       right_mark -= 1 
      if left_mark < right_mark: 
       swap(arr, right_mark, left_mark) 
       right_mark -= 1 
       left_mark += 1 
      else: 
       if arr[pivot] > arr[right_mark]: 
        swap(arr, right_mark, pivot) 
       stop = False 
     quick_sort(arr, start, right_mark - 1) 
     quick_sort(arr, right_mark, end) 

array = [8, 6, 1, 7, 0, 5, 4, 3, 2, 1] 
quick_sort(array) # in-place 
print(array) # now sorted 

IMO,下面是更清晰,更密切算法的典型描述相符:

def quick_sort(arr, start=0, end=None): 
    if end is None: 
     end = len(arr) - 1 

    if end <= start: 
     return 

    pivot = arr[start] 
    left_mark = start - 1 
    right_mark = end + 1 

    while left_mark < right_mark: 
     left_mark += 1 
     while arr[left_mark] < pivot: 
      left_mark += 1 

     right_mark -= 1 
     while arr[right_mark] > pivot: 
      right_mark -= 1 

     if left_mark < right_mark: 
      arr[left_mark], arr[right_mark] = arr[right_mark], arr[left_mark] 

    quick_sort(arr, start, right_mark) 
    quick_sort(arr, right_mark + 1, end) 
0

你是完全正確的! leftrightsplit_array之後的獨立實體,而不是原始arr的部分。在quick_sort(right)之後,比如arr=left+right。我認爲這樣做。 (需要檢查的情況下,當有在任一leftright只有一個元素是)

+0

這是正確的想法,但看到我的答案爲什麼這仍然行不通。 ('left'和'right'永遠不會被修改。) – smarx