簡體   English   中英

Python最大遞歸深度

[英]Python Max Recursion Depth

我正在Python中實現某種排序算法,遇到了一個與超出最大遞歸深度有關的怪異錯誤。 在一個模塊中,我實現了插入,合並和快速排序。 然后,我在單獨的模塊中運行一些單元測試。 快速排序大值給我遞歸深度超出錯誤。 這是我在“ Sorter.py”中算法的實現:

class QuickSort(Sorter):
    """Implements quicksort algorithm.
    Best case: O(n*log(n))
    Worst case: O(n^2)
    Average case: O(n*log(n))
    """
    @staticmethod
    def partition(numbers, low, high):
        pivot_index = low #crappy way to pick a pivot but it'll do
        pivot_val = numbers[pivot_index]

        #swap pivot with high
        temp = numbers[high]
        numbers[high] = pivot_val
        numbers[pivot_index] = temp

        store_index = low
        for index in range(low, high):
            if numbers[index] < pivot_val:
                #Swap 'index' with 'store_index'
                temp = numbers[store_index]
                numbers[store_index] = numbers[index]
                numbers[index] = temp

                store_index += 1

        #Swap pivot_val at high into appropriate index
        temp = numbers[store_index]
        numbers[store_index] = numbers[high] 
        numbers[high] = temp

        return store_index

    @staticmethod
    def sort_helper(numbers, low, high):
        if low < high:
            part_index = QuickSort.partition(numbers, low, high)
            QuickSort.sort_helper(numbers, low, part_index)
            QuickSort.sort_helper(numbers, part_index+1, high)
        return numbers  

    @classmethod
    def sort(cls, numbers):
        assert len(numbers) != 0, "Must provide a non-empty list"
        return QuickSort.sort_helper(numbers, 0, len(numbers)-1)

我可以在此模塊中運行以下測試:

 if __name__ == '__main__':
    seq = random.sample(xrange(1,100000), 10000)
    print 'Original Seq: ', seq
    real = sorted(seq)
    quick = QuickSort.sort(seq)
    print "Real Sorted: ", real
    print 'Quick Sorted: ', quick

在我的unittest模塊中,我運行以下作為測試:

def test_really_large(self):
    """Tests handling of a very large sequence."""
    test_list = random.sample(xrange(1,10000), 5000)
    real_sorted = sorted(test_list)
    insert_sorted = InsertionSort.sort(test_list)
    merge_sorted = MergeSort.sort(test_list)
    quick_sorted = QuickSort.sort(test_list)

    self.assertEqual(real_sorted, insert_sorted)
    self.assertEqual(real_sorted, merge_sorted)
    self.assertEqual(real_sorted, quick_sorted)

令我困惑的是,僅當我運行unittest模塊時才會引發錯誤。 當我嘗試對5000個整數進行排序時,出現錯誤。 但是,當我在另一個模塊中運行單個quicksort測試時,我可以對超過20000個整數進行排序,而不會引發錯誤。 為什么會這樣呢?


感謝大家的快速反應。 我認為每個人都正確地指出,我選擇支點的偽劣方法是造成已經排序的列表出現問題。 我將對此進行適當的修改。

對列表進行排序后,您的遞歸操作將無法終止。

正如Rawing指出的那樣,您看到它僅在單元測試中失敗的原因是,所有方法都在適當的地方修改了列表:因此test_list已經在對InsertionSort的調用之后進行了排序。

您應該使用單獨的單元測試方法測試每個分類器,每次都重新創建測試數據。

您的quicksort算法在排序列表時非常不好。 您的pivot_val是第一個數字,因此,已排序的列表分為一個數字和其余的數字。 對於隨機列表,所需的遞歸類似於log_2 N,這意味着對於20000個元素,深度約為15。在排序的情況下,5000個元素的遞歸深度為5000。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM