算法

1.常见算法

  • 冒泡排序:重复数列,一次比较两个元素,如果顺序错误就交换
点击查看代码
public static void BubblingSort(int[] array) {
    // 外层循环遍历数组的所有元素
    for (int i = 0; i < array.Length; i++) {
        // 内层循环从数组的末尾开始,向前遍历
        for (int j = array.Length - 1; j > 0; j--) {
            // 比较相邻的两个元素
            if (array[j] < array[j - 1]) {
                // 如果后面的元素小于前面的元素,则交换它们的位置
                int temp = array[j];
                array[j] = array[j - 1];
                array[j - 1] = temp;
            }
        }
    }
}
* 选择排序:每次选择未排序的部分最大或最小元素,放到已排序末尾
点击查看代码
public static void SelectionSort(int[] array) {
    // 外层循环控制排序的轮数,每轮都会确定一个元素的位置
    for (int i = 0; i < array.Length - 1; i++) {
        // 假设当前索引i为起始未排序部分的最小值
        int minIndex = i;

        // 内层循环用于寻找未排序部分的最小值
        for (int j = i + 1; j < array.Length; j++) {
            // 如果找到更小的值,更新最小值的索引
            if (array[j] < array[minIndex]) {
                minIndex = j;
            }
        }

        // 如果最小值不是当前轮的起始位置,交换它们
        if (minIndex != i) {
            // 交换位置i和minIndex的元素
            int temp = array[i];
            array[i] = array[minIndex];
            array[minIndex] = temp;
        }
    }
}
* 插入排序:将未排序的元素逐个插入到已排序部分的合适位置
点击查看代码
public static void InsertionSort(int[] array) {
    // 外层循环从第二个元素开始,因为第一个元素默认是已排序的
    for (int i = 1; i < array.Length; i++) {
        // 保存当前元素的值,因为如果需要插入,当前元素将被覆盖
        int currentValue = array[i];
        int j = i - 1;
        
        // 内层循环在已排序的部分从后向前扫描
        // 找到比当前元素小的元素,或者到达已排序部分的开始
        while (j >= 0 && array[j] > currentValue) {
            // 将较大的元素向后移动一位
            array[j + 1] = array[j];
            j--;
        }
        
        // 将当前元素插入到正确的位置
        array[j + 1] = currentValue;
    }
}
* 快速排序:选择一个基准元素,将小于的放左边,大的放右边,再对左右递归进行快排
点击查看代码
public static void QuickSort(int[] array, int low, int high) {
    if (low < high) {
        // 执行分区操作,找到基准元素的最终位置
        int pivotIndex = Partition(array, low, high);

        // 对基准元素左边的子数组进行快速排序
        QuickSort(array, low, pivotIndex - 1);

        // 对基准元素右边的子数组进行快速排序
        QuickSort(array, pivotIndex + 1, high);
    }
}

private static int Partition(int[] array, int low, int high) {
    // 选择基准元素,这里选择最后一个元素作为基准
    int pivot = array[high];
    int i = low - 1; // 小于基准的元素的索引

    // 遍历数组,将小于基准的元素移动到左边
    for (int j = low; j < high; j++) {
        if (array[j] < pivot) {
            i++; // 发现小于基准的元素,递增i
            // 交换元素,将小于基准的元素移动到左边
            Swap(array, i, j);
        }
    }

    // 交换基准元素到它最终的位置
    Swap(array, i + 1, high);
    return i + 1; // 返回基准元素的最终位置
}

private static void Swap(int[] array, int i, int j) {
    int temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}
* 归并排序:将数组分成两半,对每一半进行递归归并排序,再将两个有序的子数组合并成一个有序数组。
点击查看代码
public static void MergeSort(int[] array, int left, int right) {
    if (left < right) {
        // 找到中间位置,将数组分成左右两部分
        int middle = left + (right - left) / 2;

        // 递归地对左边的子数组进行归并排序
        MergeSort(array, left, middle);

        // 递归地对右边的子数组进行归并排序
        MergeSort(array, middle + 1, right);

        // 合并两个有序的子数组
        Merge(array, left, middle, right);
    }
}

private static void Merge(int[] array, int left, int middle, int right) {
    // 创建临时数组,用于存放合并后的元素
    int n1 = middle - left + 1;
    int n2 = right - middle;

    int[] leftArray = new int[n1];
    int[] rightArray = new int[n2];

    // 拷贝数据到临时数组
    Array.Copy(array, left, leftArray, 0, n1);
    Array.Copy(array, middle + 1, rightArray, 0, n2);

    int i = 0, j = 0, k = left;

    // 合并两个临时数组到原数组
    while (i < n1 && j < n2) {
        if (leftArray[i] <= rightArray[j]) {
            array[k++] = leftArray[i++];
        } else {
            array[k++] = rightArray[j++];
        }
    }

    // 拷贝左边剩余的元素
    while (i < n1) {
        array[k++] = leftArray[i++];
    }

    // 拷贝右边剩余的元素
    while (j < n2) {
        array[k++] = rightArray[j++];
    }
}
* 希尔排序:将数组划分成若干个间隔相等的子序列,对每个子序列进行插入排序,随着间隔逐步减少,直至间隔为1,最终对整个数组进行插入排序,使得整个数组基本有序。
点击查看代码
public static void ShellSort(int[] array) {
    int n = array.Length;
    // 初始间隔值,可以取为 n/2, n/4, ..., 1
    int gap = n / 2;

    // 当间隔值大于 0 时,继续执行
    while (gap > 0) {
        // 对每个子序列进行插入排序
        for (int i = gap; i < n; i++) {
            int temp = array[i];
            int j = i;

            // 将当前元素与子序列中的其他元素进行比较
            while (j >= gap && array[j - gap] > temp) {
                array[j] = array[j - gap];
                j -= gap;
            }
            array[j] = temp;
        }
        // 减少间隔值
        gap /= 2;
    }
}
* 堆排序:将数组构建成最大堆,然后将堆顶元素和最后一个元素交换并重新调整堆,直到所有元素都排好序。
点击查看代码
public static void HeapSort(int[] array) {
    int n = array.Length;

    // 构建最大堆
    for (int i = n / 2 - 1; i >= 0; i--) {
       Heapify(array, n, i);
    }

    // 进行堆排序
    for (int i = n - 1; i > 0; i--) {
        // 将堆顶元素(最大值)与数组末尾元素交换
        int temp = array[0];
        array[0] = array[i];
        array[i] = temp;

        // 重新调整堆
        Heapify(array, i, 0);
    }
}

private static void Heapify(int[] array, int n, int i) {
    int largest = i; // 初始化最大值为根节点
    int left = 2 * i + 1; // 左子节点
    int right = 2 * i + 2; // 右子节点

    // 如果左子节点大于根节点,则更新最大值
    if (left < n && array[left] > array[largest]) {
        largest = left;
    }

    // 如果右子节点大于当前最大值,则更新最大值
    if (right < n && array[right] > array[largest]) {
        largest = right;
    }

    // 如果最大值不是根节点,交换它们,并继续调整堆
    if (largest != i) {
        int temp = array[i];
        array[i] = array[largest];
        array[largest] = temp;

        // 递归地调整受影响的子树
        Heapify(array, n, largest);
    }
}
* 桶排序:将元素分配到有限数量的桶中,对桶中每个元素进行排序,然后按照顺序将桶中元素输出。
点击查看代码
public static void BucketSort(int[] array) {
    if (array == null || array.Length == 0) {
        return;
    }

    // 确定桶的数量,这里简单地取数组长度
    int bucketCount = array.Length;
    int[] buckets = new int[bucketCount][];
    int max = array.Max();
    int min = array.Min();

    // 计算每个桶的宽度
    double bucketWidth = (double)(max - min) / bucketCount;

    // 分配元素到各个桶中
    for (int i = 0; i < array.Length; i++) {
        int index = (int)((array[i] - min) / bucketWidth);
        if (index < 0) {
            index = 0;
        }
        if (index >= bucketCount) {
            index = bucketCount - 1;
        }

        // 初始化桶
        if (buckets[index] == null) {
            buckets[index] = new int[bucketCount];
        }

        // 将元素添加到桶中
        buckets[index].Add(array[i]);
    }

    // 对每个桶进行排序,并合并结果
    int index = 0;
    for (int i = 0; i < buckets.Length; i++) {
        if (buckets[i] != null) {
            // 对桶中的元素进行插入排序
            InsertionSort(buckets[i]);
            // 将已排序的桶中的元素添加到结果数组中
            for (int j = 0; j < buckets[i].Length; j++) {
                array[index++] = buckets[i][j];
            }
        }
    }
}

private static void InsertionSort(int[] array) {
    for (int i = 1; i < array.Length; i++) {
        int key = array[i];
        int j = i - 1;

        while (j >= 0 && array[j] > key) {
            array[j + 1] = array[j];
            j--;
        }
        array[j + 1] = key;
    }
}
posted @ 2024-10-17 17:00  doudouqie66  阅读(6)  评论(0编辑  收藏  举报