算法
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++];
}
}
点击查看代码
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;
}
}