氣泡排序演演算法是一種基礎的排序演演算法,它的實現原理比較簡單。核心思想是通過相鄰元素的比較和交換來將最大(或最小)的元素逐步"冒泡"到數列的末尾。
https://mp.weixin.qq.com/s/z_LPZ6QUFNJcwaEw_H5qbQ
/// <summary>
/// 遞迴方式實現氣泡排序
/// </summary>
/// <param name="arr">arr</param>
/// <param name="arrLength">arrLength</param>
public static void RecursiveBubbleSort(int[] arr, int arrLength)
{
if (arrLength == 1)
return;
for (int i = 0; i < arrLength - 1; i++)
{
if (arr[i] > arr[i + 1])
{
//交換arr[i]和arr[i+1]的值
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
RecursiveBubbleSort(arr, arrLength - 1);
}
public static void RecursiveBubbleSortRun()
{
int[] arr = { 1, 8, 9, 5, 6, 2, 3, 4, 7 };
int arrLength = arr.Length;
RecursiveBubbleSort(arr, arrLength);
Console.WriteLine("排序後結果:" + string.Join(", ", arr));
}
選擇排序演演算法的基本思想是每一次從待排序的資料元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到全部待排序的資料元素排完。
https://mp.weixin.qq.com/s/B1QdqyP8HQgOv8tlSujtog
/// <summary>
/// 選擇排序演演算法
/// </summary>
public static void SelectionSortAlgorithmMain()
{
int[] array = { 64, 25, 12, 22, 11, 99, 3, 100 };
Console.WriteLine("原始陣列: ");
PrintArray(array);
SelectionSortAlgorithm(array);
Console.WriteLine("排序後的陣列: ");
PrintArray(array);
}
static void SelectionSortAlgorithm(int[] arr)
{
int n = arr.Length;
for (int i = 0; i < n - 1; i++)
{
// 在未排序部分中找到最小元素的索引
int minIndex = i;
for (int j = i + 1; j < n; j++)
{
if (arr[j] < arr[minIndex])
{
minIndex = j;
}
}
// 將最小元素與未排序部分的第一個元素交換位置
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
static void PrintArray(int[] arr)
{
int n = arr.Length;
for (int i = 0; i < n; ++i)
{
Console.Write(arr[i] + " ");
}
Console.WriteLine();
}
插入排序演演算法是一種簡單、直觀的排序演演算法,其原理是將一個待排序的元素逐個地插入到已經排好序的部分中。
https://mp.weixin.qq.com/s/YEregZ_GOGgEltGUJadycw
public static void InsertionSort(int[] array)
{
int arrayLength = array.Length;//陣列長度(時間複雜度為O(n^2))
for (int i = 1; i < arrayLength; ++i)
{
//定義臨時變數
int temp = array[i];
int j = i - 1;
while (j >= 0 && array[j] > temp)
{
array[j + 1] = array[j];
j--;
}
array[j + 1] = temp;
}
}
public static void InsertionSortRun()
{
int[] array = { 26, 15, 5, 3, 38, 36, 44, 27, 47, 2, 46, 4, 50, 19, 48 };
Console.WriteLine("排序前:" + string.Join(", ", array));
InsertionSort(array);
Console.WriteLine("排序後:" + string.Join(", ", array));
}
希爾排序簡單的來說就是一種改進的插入排序演演算法,它通過將待排序的元素分成若干個子序列,然後對每個子序列進行插入排序,最終逐步縮小子序列的間隔,直到整個序列變得有序。希爾排序的主要思想是通過插入排序的優勢,減小逆序對的距離,從而提高排序效率。
https://mp.weixin.qq.com/s/_t9QVuj_rLcNomyv7LcGMA
public static void ShellSort(int[] array)
{
int arrLength = array.Length;
// 初始化增量(初始間隔)為陣列長度的一半
int gap = arrLength / 2;
// 不斷縮小增量,直到增量為1
while (gap > 0)
{
// 對每個子序列進行插入排序
for (int i = gap; i < arrLength; 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 ShellSortRun()
{
int[] array = { 19, 20, 22, 32, 34, 50, 99, 49, 1, 11, 11, 55, 35, 93, 96, 71, 70, 38, 78, 48 };
Console.WriteLine("排序前陣列:" + string.Join(", ", array));
ShellSort(array);
Console.WriteLine("排序後陣列:" + string.Join(", ", array));
}
歸併排序是一種常見的排序演演算法,它採用分治法的思想,在排序過程中不斷將待排序序列分割成更小的子序列,直到每個子序列中只剩下一個元素,然後將這些子序列兩兩合併排序,最終得到一個有序的序列。
https://mp.weixin.qq.com/s/ToURWBfVIl7087Ago8fGdQ
public static void MergeSort(int[] arr, int left, int right)
{
if (left < right)
{
// 計算中間索引
int mid = (left + right) / 2;
// 對左半部分陣列進行歸併排序
MergeSort(arr, left, mid);
// 對右半部分陣列進行歸併排序
MergeSort(arr, mid + 1, right);
// 合併兩個有序陣列
Merge(arr, left, mid, right);
}
}
public static void Merge(int[] arr, int left, int mid, int right)
{
int n1 = mid - left + 1; // 左半部分陣列的長度
int n2 = right - mid; // 右半部分陣列的長度
// 建立臨時陣列
int[] leftArr = new int[n1];
int[] rightArr = new int[n2];
// 將資料拷貝到臨時陣列
for (int i = 0; i < n1; ++i)
{
leftArr[i] = arr[left + i];
}
for (int j = 0; j < n2; ++j)
{
rightArr[j] = arr[mid + 1 + j];
}
// 合併兩個有序陣列
int k = left; // 初始化合並後的陣列索引
int p = 0; // 初始化左半部分陣列的索引
int q = 0; // 初始化右半部分陣列的索引
while (p < n1 && q < n2)
{
if (leftArr[p] <= rightArr[q])
{
arr[k] = leftArr[p];
p++;
}
else
{
arr[k] = rightArr[q];
q++;
}
k++;
}
// 複製左半部分陣列的剩餘元素
while (p < n1)
{
arr[k] = leftArr[p];
p++;
k++;
}
// 複製右半部分陣列的剩餘元素
while (q < n2)
{
arr[k] = rightArr[q];
q++;
k++;
}
}
public static void MergeSortRun()
{
int[] array = { 19, 27, 46, 48, 50, 2, 4, 44, 47, 36, 38, 15, 26, 5, 3 };
Console.WriteLine("排序前陣列:" + string.Join(", ", array));
MergeSort(array, 0, array.Length - 1);
Console.WriteLine("排序後陣列:" + string.Join(", ", array));
}
快速排序是一種常用的排序演演算法,它基於分治的思想,通過將一個無序的序列分割成兩個子序列,並遞迴地對子序列進行排序,最終完成整個序列的排序。
https://mp.weixin.qq.com/s/7vms2Q4s7DBdFs31w4cfVA
public class 快速排序演演算法
{
public static void Sort(int[] array, int low, int high)
{
if (low < high)
{
//將陣列分割為兩部分,並返回分割點的索引
int pivotIndex = Partition(array, low, high);
//遞迴對分割後的兩部分進行排序
Sort(array, low, pivotIndex - 1);
Sort(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 - 1; j++)
{
//如果當前元素小於等於基準元素,則將它與i+1位置的元素交換
if (array[j] <= pivot)
{
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 QuickSortRun()
{
int[] array = { 2, 3, 5, 38, 19, 15, 26, 27, 36, 44, 47, 46, 50, 48, 4 };
Sort(array, 0, array.Length - 1);
Console.WriteLine("排序後結果:" + string.Join(", ", array));
}
}
堆排序是一種高效的排序演演算法,基於二元堆積資料結構實現。它具有穩定性、時間複雜度為O(nlogn)和空間複雜度為O(1)的特點。
https://mp.weixin.qq.com/s/zS_ESKzlg05ICqFPIaePkg
public static void HeapSort(int[] array)
{
int arrayLength = array.Length;
//構建最大堆
for (int i = arrayLength / 2 - 1; i >= 0; i--)
Heapify(array, arrayLength, i);
//依次取出堆頂元素,並重新調整堆
for (int i = arrayLength - 1; i >= 0; i--)
{
//將堆頂元素與當前最後一個元素交換
int temp = array[0];
array[0] = array[i];
array[i] = temp;
//重新調整堆
Heapify(array, i, 0);
}
}
private static void Heapify(int[] arr, int n, int i)
{
int largest = i; //假設父節點最大
int left = 2 * i + 1; //左子節點
int right = 2 * i + 2; //右子節點
//如果左子節點大於父節點,則更新最大值
if (left < n && arr[left] > arr[largest])
largest = left;
//如果右子節點大於父節點和左子節點,則更新最大值
if (right < n && arr[right] > arr[largest])
largest = right;
//如果最大值不是當前父節點,則交換父節點和最大值,並繼續向下調整堆
if (largest != i)
{
int swap = arr[i];
arr[i] = arr[largest];
arr[largest] = swap;
Heapify(arr, n, largest);
}
}
public static void HeapSortRun()
{
int[] array = { 19, 27, 46, 48, 50, 2, 4, 44, 47, 36, 38, 15, 26, 5, 3, 99, 888, 0, -1 };
Console.WriteLine("排序前陣列:" + string.Join(", ", array));
HeapSort(array);
Console.WriteLine("排序後陣列:" + string.Join(", ", array));
}
計數排序是一種非比較性的排序演演算法,適用於排序一定範圍內的整數。它的基本思想是通過統計每個元素的出現次數,然後根據元素的大小依次輸出排序結果。
https://mp.weixin.qq.com/s/PA5NNqcy3CM9PSncWCsmEg
public static void CountingSort(int[] array)
{
int arrayLength = array.Length;
if (arrayLength <= 1) return;
int min = array[0];
int max = array[0];
//找出最大值和最小值
for (int i = 1; i < arrayLength; i++)
{
if (array[i] < min) min = array[i];
if (array[i] > max) max = array[i];
}
//統計每個元素出現的次數
int[] count = new int[max - min + 1];
//統計每個元素出現的次數
for (int i = 0; i < arrayLength; i++)
{
count[array[i] - min]++;
}
//根據count陣列和min值確定每個元素的起始位置
for (int i = 1; i < count.Length; i++)
{
count[i] += count[i - 1];
}
//儲存排序結果
int[] temp = new int[arrayLength];
//根據count陣列和min值確定每個元素在temp陣列中的位置
for (int i = arrayLength - 1; i >= 0; i--)
{
int index = count[array[i] - min] - 1;
temp[index] = array[i];
count[array[i] - min]--;
}
//將排序結果複製回原陣列
for (int i = 0; i < arrayLength; i++)
{
array[i] = temp[i];
}
}
public static void CountingSortRun()
{
int[] array = { 19, 27, 46, 48, 50, 2, 4, 44, 47, 36, 38, 15, 26, 5, 3, 99, 888};
Console.WriteLine("排序前陣列:" + string.Join(", ", array));
CountingSort(array);
Console.WriteLine("排序後陣列:" + string.Join(", ", array));
}
桶排序是一種線性時間複雜度的排序演演算法,它將待排序的資料分到有限數量的桶中,每個桶再進行單獨排序,最後將所有桶中的資料按順序依次取出,即可得到排序結果。
https://mp.weixin.qq.com/s/YzviDcm3-4E5Wf2jooylJQ
public static void BucketSort(int[] array)
{
int arrLength = array.Length;
if (arrLength <= 1)
{
return;
}
//確定桶的數量
int maxValue = array[0], minValue = array[0];
for (int i = 1; i < arrLength; i++)
{
if (array[i] > maxValue)
maxValue = array[i];
if (array[i] < minValue)
minValue = array[i];
}
int bucketCount = (maxValue - minValue) / arrLength + 1;
//建立桶並將資料放入桶中
List<List<int>> buckets = new List<List<int>>(bucketCount);
for (int i = 0; i < bucketCount; i++)
{
buckets.Add(new List<int>());
}
for (int i = 0; i < arrLength; i++)
{
int bucketIndex = (array[i] - minValue) / arrLength;
buckets[bucketIndex].Add(array[i]);
}
//對每個非空的桶進行排序
int index = 0;
for (int i = 0; i < bucketCount; i++)
{
if (buckets[i].Count == 0)
{
continue;
}
int[] tempArr = buckets[i].ToArray();
Array.Sort(tempArr);
foreach (int num in tempArr)
{
array[index++] = num;
}
}
}
public static void BucketSortRun()
{
int[] array = { 19, 27, 46, 48, 50, 2, 4, 44, 47, 36, 38, 15, 26, 5, 3, 99, 888};
Console.WriteLine("排序前陣列:" + string.Join(", ", array));
BucketSort(array);
Console.WriteLine("排序後陣列:" + string.Join(", ", array));
}
基數排序是一種非比較性排序演演算法,它通過將待排序的資料拆分成多個數位位進行排序。
https://mp.weixin.qq.com/s/dCG-LLim4UGD1kIY2a3hmA
public static void RadixSort(int[] array)
{
if (array == null || array.Length < 2)
{
return;
}
//獲取陣列中的最大值,確定排序的位數
int max = GetMaxValue(array);
//進行基數排序
for (int exp = 1; max / exp > 0; exp *= 10)
{
CountingSort(array, exp);
}
}
private static void CountingSort(int[] array, int exp)
{
int arrayLength = array.Length;
int[] output = new int[arrayLength];
int[] count = new int[10];
//統計每個桶中的元素個數
for (int i = 0; i < arrayLength; i++)
{
count[(array[i] / exp) % 10]++;
}
//計算每個桶中最後一個元素的位置
for (int i = 1; i < 10; i++)
{
count[i] += count[i - 1];
}
//從原陣列中取出元素,放入到輸出陣列中
for (int i = arrayLength - 1; i >= 0; i--)
{
output[count[(array[i] / exp) % 10] - 1] = array[i];
count[(array[i] / exp) % 10]--;
}
//將輸出陣列複製回原陣列
for (int i = 0; i < arrayLength; i++)
{
array[i] = output[i];
}
}
private static int GetMaxValue(int[] arr)
{
int max = arr[0];
for (int i = 1; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
public static void RadixSortRun()
{
int[] array = { 19, 27, 46, 48, 99, 888, 50, 2, 4, 44, 47, 36, 38, 15, 26, 5, 3 };
Console.WriteLine("排序前陣列:" + string.Join(", ", array));
RadixSort(array);
Console.WriteLine("排序後陣列:" + string.Join(", ", array));
}
1、提供.NET開發者分享自己優質文章的群組和獲取更多全面的C#/.NET/.NET Core學習資料、視訊、文章、書籍,社群組織,工具和常見面試題資源,幫助大家更好地瞭解和使用 .NET技術。
2、在這個群裡,開發者們可以分享自己的專案經驗、遇到的問題以及解決方案,傾聽他人的意見和建議,共同成長與進步。
3、可以結識更多志同道合的開發者,甚至可能與其他開發者合作完成有趣的專案。通過這個群組,我們希望能夠搭建一個積極向上、和諧友善的.NET技術交流平臺,為廣大.NET開發者帶來更多的價值。