我想问一下我创建的排序通用类。我使用了今年学到的许多不同概念,并将其组合到一个不错的类中,该类可以用来对任何东西进行排序(当然,如果该类是一个类,则该类具有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);
}
}
}
答案 0 :(得分:5)
这是因为List<T>
是Reference Type。
C#中有两种类型:引用类型和值类型。引用类型的变量存储对其数据(对象)的引用,而值类型的变量直接包含其数据。对于引用类型,两个变量可以引用相同的对象。因此,对一个变量的操作会影响另一变量引用的对象。对于值类型,每个变量都有其自己的数据副本,并且对一个变量的操作不可能影响另一个变量(除非in,ref和out参数变量;请参阅in,ref和out参数修饰符)。
在您的示例中,变量toSort
和私有字段Sort.toSort
都引用完全相同的列表。
答案 1 :(得分:1)
如果您操纵作为参数传递的集合,那么将为每个能够访问该集合的同一实例的类进行操纵,这就是为什么您实际上不需要返回新的Lost的原因。
要了解有关引用和值类型的更多信息,请阅读: Value Types Reference Types
如果您想了解.net框架如何帮助您进行集合排序,请阅读here
答案 2 :(得分:0)
您有一个将列表作为参数的类构造函数,并且正在对该列表进行排序。
基本上此代码:
private List<T> toSort;
public Sort(List<T> sortList)
{
toSort = sortList;
quickSort();
}
现在,List<T>
是一种引用类型,这意味着如果将其作为参数传递给其他修改它的代码,则调用代码将看到修改后的列表。
答案 3 :(得分:-1)
之所以起作用,是因为您正在进行就地排序。没有列表的副本,所有更改都在您引用类型传递的原始列表上进行。数组和引用类型的任何其他传递都可以使用相同的东西。
如果我建议让您的代码更快一点,更干净一点,那就是使用通用静态方法,如下所示:
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);