簡體   English   中英

使用遞歸和泛型創建快速排序

[英]Creating a quick sort using recursion and generics

我想問一下我創建的排序通用類。 我使用了今年學到的許多不同概念,並將其組合到一個不錯的類中,該類可以用來對任何東西進行排序(當然,如果它是一個類,則該類具有CompareTo方法)

public class Sort<T> where T : IComparable<T>
    {
        private List<T> toSort;
        public Sort(List<T> sortList)
        {
            toSort = sortList;
            quickSort();
        }
        public void quickSort()
        {
            qSort(toSort, 0, toSort.Count - 1);
        }
        private void qSort(List<T> toSort, int left, int right)
        {
            //set the indexes
            int leftIndex = left;
            int rightIndex = right;

            //get the pivot
            var pivot = toSort[left + (right - left) / 2];
            while (leftIndex <= rightIndex)
            {
                //check left values
                while (toSort[leftIndex].CompareTo(pivot)<0)
                {
                    leftIndex++;
                }
                //check right values
                while (toSort[rightIndex].CompareTo(pivot) >0)
                {
                    rightIndex--;
                }
                //swap
                if (leftIndex <= rightIndex)
                {
                    var tmp = toSort[leftIndex];
                    toSort[leftIndex] = toSort[rightIndex];
                    toSort[rightIndex] = tmp;

                    //move towards pivot
                    leftIndex++;
                    rightIndex--;
                }
            }
            //continues to sort left and right of pivot
            if (left < rightIndex)
            {
                qSort(toSort, left, rightIndex);
            }
            if (leftIndex < right)
            {
                qSort(toSort, leftIndex, right);
            }
        }


    }

我只有一個問題,就是我在互聯網上使用的quickSort,然后自己將其轉換為使用泛型。 我了解實際排序的工作方式。 我只想知道,為什么我不必退貨。 我有點困惑。 我看到它實際上是在切換列表的值,但是我不知道它如何訪問我發送的列表。 因為在我稱之為的地方我可以做到這一點

List<string> toSort = new List<string> { "C", "B", "A" };
                Sort<string> sort = new Sort<string>(toSort);
                cbxAlphabet.DataSource = toSort;

因此,我只使用原始列表,並且comboBox中將包含A,B和C。

如果有人可以解釋這一點,我將不勝感激!

編輯:

 public static class Sort<T> where T : IComparable<T>
    {
        public static void quickSort(List<T> sortList)
        {
            qSort(sortList, 0, sortList.Count - 1);
        }
        private static void qSort(List<T> toSort, int left, int right)
        {
            //set the indexes
            int leftIndex = left;
            int rightIndex = right;

            //get the pivot
            var pivot = toSort[left + (right - left) / 2];
            while (leftIndex <= rightIndex)
            {
                //check left values
                while (toSort[leftIndex].CompareTo(pivot)<0)
                {
                    leftIndex++;
                }
                //check right values
                while (toSort[rightIndex].CompareTo(pivot) >0)
                {
                    rightIndex--;
                }
                //swap
                if (leftIndex <= rightIndex)
                {
                    var tmp = toSort[leftIndex];
                    toSort[leftIndex] = toSort[rightIndex];
                    toSort[rightIndex] = tmp;

                    //move towards pivot
                    leftIndex++;
                    rightIndex--;
                }
            }
            //continues to sort left and right of pivot
            if (left < rightIndex)
            {
                qSort(toSort, left, rightIndex);
            }
            if (leftIndex < right)
            {
                qSort(toSort, leftIndex, right);
            }
        }


    }

這是因為List<T>引用類型

C#中有兩種類型:引用類型和值類型。 引用類型的變量存儲對其數據(對象)的引用,而值類型的變量直接包含其數據。 對於引用類型,兩個變量可以引用相同的對象。 因此,對一個變量的操作會影響另一變量引用的對象。 對於值類型,每個變量都有其自己的數據副本,並且對一個變量的操作不可能影響另一個變量(除非是in,ref和out參數變量;請參閱in,ref和out參數修飾符)。

在您的示例中,變量toSort和私有字段Sort.toSort都引用完全相同的列表。

如果您對作為參數傳遞的集合進行操作,那么它將為每個能夠訪問該集合的同一實例的類進行操作,這就是為什么您實際上不需要返回新的lost的原因。

要了解有關引用和值類型的更多信息,請閱讀: 值類型 引用類型

如果您想了解.net框架如何幫助您進行集合排序,請閱讀此處

您有一個類構造函數,期望將列表作為參數,並對列表進行排序。

基本上這段代碼:

private List<T> toSort;
public Sort(List<T> sortList)
{
    toSort = sortList;
    quickSort();
}

現在, List<T>是引用類型,這意味着如果將其作為參數傳遞給其他修改它的代碼,則調用代碼將看到修改后的列表。

之所以起作用,是因為您正在就地排序 不創建列表的副本,並且所有更改都在通過Reference Type傳遞的原始列表上進行。 數組和引用類型的任何其他傳遞都可以使用相同的方法。

如果我建議讓您的代碼更快一點,更干凈一點,那就是使用通用靜態方法,如下所示:

public static class SortMethods
{
    public static <T> List<T> QuickSort(this List<T> toSort) where T : IComparable<T>
    {
        QuickSort(toSort, 0, toSort.Count - 1);
        return toSort;
    }
    private static <T> void QuickSort(this List<T> toSort, int left, int right) where T : IComparable<T>
    {
        // perform quick sort
    }
}

然后,您可以使用以下兩種方法之一進行調用:

  • list.QuickSort();
  • SortMethods.QuickSort(list);

暫無
暫無

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

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