簡體   English   中英

為什么我的快速排序這么慢?

[英]Why is my quick sort so slow?

我正在練習編寫排序算法作為一些面試准備的一部分,我想知道是否有人可以幫助我發現為什么這種快速排序不是很快? 它似乎具有正確的運行時復雜性,但它比我的合並排序慢了大約2的常數因子。我也很感激任何可以改進我的代碼的注釋,但不一定能回答這個問題。

非常感謝你的幫助! 如果我犯了禮儀錯誤,請不要猶豫,告訴我。 這是我的第一個問題。

private class QuickSort implements Sort {

        @Override
        public int[] sortItems(int[] ts) {
            List<Integer> toSort = new ArrayList<Integer>();
            for (int i : ts) {
                toSort.add(i);
            }
            toSort = partition(toSort);
            int[] ret = new int[ts.length];
            for (int i = 0; i < toSort.size(); i++) {
                ret[i] = toSort.get(i);
            }
            return ret;
        }

        private List<Integer> partition(List<Integer> toSort) {
            if (toSort.size() <= 1)
                return toSort;
            int pivotIndex = myRandom.nextInt(toSort.size());
            Integer pivot = toSort.get(pivotIndex);
            toSort.remove(pivotIndex);
            List<Integer> left = new ArrayList<Integer>();
            List<Integer> right = new ArrayList<Integer>();
            for (int i : toSort) {
                if (i > pivot)
                    right.add(i);
                else
                    left.add(i);
            }
            left = partition(left);
            right = partition(right);
            left.add(pivot);
            left.addAll(right);
            return left;
        }

}

非常感謝,所有幫助過的人!

這是我為子孫后代改進的課程:

private class QuickSort implements Sort {

        @Override
        public int[] sortItems(int[] ts) {
            int[] ret = ts.clone();
            partition(ret,0,ret.length);
            return ret;
        }

        private void partition(int[] toSort,int start,int end) {
            if(end-start<1) return;
            int pivotIndex = start+myRandom.nextInt(end-start);
            int pivot = toSort[pivotIndex];
            int curSorted = start;
            swap(toSort,pivotIndex,start);
            for(int j = start+1; j < end; j++) {
                if(toSort[j]<pivot) {
                    if(j!=curSorted+1) 
                        swap(toSort,curSorted,curSorted+1);
                    swap(toSort,j,curSorted++);
                }
            }
            // Now pivot is at curSorted
            partition(toSort,start,curSorted);
            partition(toSort,curSorted+1,end);
        }
    }

Quicksort最大的優勢之一是它可以作為就地算法實現。 不要創建新列表,而是在原地對元素進行排序。

除了不重用列表之外,還可以在每個步驟中在Integer和int之間進行轉換:

        for (int i : toSort) {  // converts from Integer to int
            if (i > pivot)
                right.add(i);  // converts from int to Integer
            else
                left.add(i);   // converts from int to Integer
        }

請注意,從int到Integer的轉換通常需要創建一個新對象。

最后,random.nextInt()可能是一個非平凡的操作。 如果toSort超過一定的大小並且使用更簡單的樞軸選擇策略,那么最好只選擇一個隨機的樞軸(測量它!)。

暫無
暫無

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

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