泛型快排

本文详细介绍了一种快速排序算法的实现过程,包括选择基准值、分区操作、递归调用等核心步骤,并提供了完整的代码实现。此外,还介绍了用于比较元素大小的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * 快排(除null)
 *
 * @param array
 * @param <C>
 */
public static <C extends Comparable> void sort(C[] array) {
    if (null == array) {
        return;
    }
    sort(array, 0, array.length - 1);
}

/**
 * 快排
 *
 * @param array
 * @param start
 * @param end
 * @param <C>
 */
private static <C extends Comparable> void sort(C[] array, int start, int end) {
    if (end - start < 1) {
        return;
    }
    select(array, start, end);
    C split = array[start];
    int i = start;
    int j = end;
    while (i < j) {
        // 找到比split小的数
        while (i < j && bigger(array[j], split)) {
            j--;
        }
        if (i < j) {
            array[i++] = array[j];
        }
        // 找到比split大的数
        while (i < j && smaller(array[i], split)) {
            i++;
        }
        if (i < j) {
            array[j--] = array[i];
        }
    }
    array[i] = split;
    // 排序左边
    sort(array, start, i - 1);
    // 排序右边
    sort(array, i + 1, end);
}

/**
 * 选择策略
 *
 * @param array
 * @param start
 * @param end
 * @param <C>
 */
private static <C extends Comparable> void select(C[] array, int start, int end) {
    int mid = start + (end - start) / 2;
    if (smaller(array[start], array[mid])) {
        swap(array, start, mid);
    } else if (smaller(array[start], array[end])) {
        swap(array, start, end);
    }
}

/**
 * 交换值
 *
 * @param array
 * @param a
 * @param b
 * @param <C>
 */
private static <C extends Comparable> void swap(C[] array, int a, int b) {
    C t = array[a];
    array[a] = array[b];
    array[b] = t;
}

@SuppressWarnings("unchecked")
public static <C extends Comparable> boolean bigger(C a, C b) {
    return a.compareTo(b) > 0;
}

@SuppressWarnings("unchecked")
public static <C extends Comparable> boolean smaller(C a, C b) {
    return a.compareTo(b) < 0;
}
<think>好的,用户想要查找关于C#实现快速排序的例子。我需要先回顾一下快速排序的基本原理,然后结合C#语言的特性来提供一个清晰的实现示例。 首先,快速排序的核心思想是分治法。选择一个基准元素,将数组分成两部分,一部分比基准小,另一部分比基准大,然后递归地对这两部分进行排序。关键点在于如何选择基准和如何进行分区操作。 在C#中,实现快速排序通常需要编写一个递归函数。基准的选择可以简单点,比如选第一个元素或者中间元素。不过要注意,如果数组已经有序,选择第一个元素可能导致最坏情况,这时候可能需要优化基准选择方法,比如三数取中。 接下来考虑分区操作。需要遍历数组,将小于基准的元素移到左边,大于的移到右边。可以用双指针法,一个从左边开始,一个从右边开始,交换不符合条件的元素,直到指针相遇。 然后需要处理递归的终止条件,当子数组长度小于等于1时,直接返回。另外,C#的参数传递是值传递,因此在函数内部对数组的修改会影响原数组,不需要额外处理。 还要注意代码的示例是否简洁易懂,是否需要处理重复元素?比如在分区时,等于基准的元素可以放在任意一边,但为了稳定性可能需要特别处理,不过快速排序本身不稳定,所以可能不需要特别考虑。 现在根据用户提供的引用[1]中的C#代码示例,虽然那个代码可能不是完整的,但可以看出Console读写文件的部分,可能用户需要的是一个完整的示例,而不仅仅是排序函数。不过用户主要关注的是实现快速排序的代码,所以应该重点展示排序的核心部分。 另外,用户可能希望代码符合C#的现代语法,比如使用列表或者数组,是否需要处理不同的数据类?比如支持int数组或者。但为了简单起见,先以int数组为例。 现在开始组织代码结构。例如: public static void QuickSort(int[] arr, int left, int right) { if (left < right) { int pivotIndex = Partition(arr, left, right); QuickSort(arr, left, pivotIndex - 1); QuickSort(arr, pivotIndex + 1, right); } } private static int Partition(int[] arr, int left, int right) { int pivot = arr[right]; // 选择最后一个元素作为基准 int i = left - 1; for (int j = left; j < right; j++) { if (arr[j] <= pivot) { i++; Swap(arr, i, j); } } Swap(arr, i + 1, right); return i + 1; } private static void Swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } 这个例子中,基准选的是最后一个元素,分区使用单边遍历,i记录小于基准的区域的末尾。这样可能更容易理解。 然后需要测试代码,比如Main函数中调用QuickSort。根据引用[1]中的代码示例,用户可能需要一个完整的控制台程序,包括输入输出。不过用户的问题可能更关注排序实现本身,所以给出核心的排序方法即可。 另外,引用[2]提到C#中的并行编程,可能用户对性能优化有兴趣,但当前问题可能不需要涉及多线程,所以暂时不展开。 最后,需要确保代码正确,比如处理边界条件,递归终止条件是否正确,分区函数是否正确返回基准的位置。 总结:提供C#实现的快速排序代码,解释核心步骤,并可能提到优化点如基准选择、尾递归优化等。同时生成相关问题,帮助用户进一步学习。</think>### C#快速排序实现示例 快速排序是一种基于分治策略的高效排序算法,其核心步骤为:**选择基准**、**分区操作**和**递归排序**。以下是C#实现示例: ```csharp using System; public class QuickSortExample { public static void Sort(int[] arr) { QuickSort(arr, 0, arr.Length - 1); } private static void QuickSort(int[] arr, int left, int right) { if (left < right) { int pivotIndex = Partition(arr, left, right); QuickSort(arr, left, pivotIndex - 1); // 递归处理左子数组 QuickSort(arr, pivotIndex + 1, right); // 递归处理右子数组 } } private static int Partition(int[] arr, int left, int right) { int pivot = arr[right]; // 选择最后一个元素为基准 int i = left - 1; // 记录小于基准区域的边界 for (int j = left; j < right; j++) { if (arr[j] <= pivot) { i++; Swap(arr, i, j); // 将小于基准的元素移动到左侧区域 } } Swap(arr, i + 1, right); // 将基准放置到正确位置 return i + 1; } private static void Swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } // 测试代码 public static void Main() { int[] data = { 9, 7, 5, 11, 12, 2 }; Sort(data); Console.WriteLine("排序结果: " + string.Join(", ", data)); } } ``` #### 关键点解析 1. **基准选择**:示例选择最后一个元素作为基准(`pivot = arr[right]`),但实际应用中可采用三数取中法优化[^1]。 2. **分区操作**:通过双指针遍历将数组划分为`[≤pivot]`和`[>pivot]`两部分。 3. **时间复杂度**:平均情况为$O(n \log n)$,最坏情况(如数组已有序)为$O(n^2)$[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值