[英]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
都引用完全相同的列表。
您有一個類構造函數,期望將列表作為參數,並對列表進行排序。
基本上這段代碼:
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.