以下是常用的11种排序算法的C语言代码实现,附带有代码注释和讲解:
1.冒泡排序
void bubble_sort(int arr[], int n)
{
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1 j if arrj> arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
冒泡排序是一种基础的排序算法。它的基本思想是重复地遍历数组,比较相邻的两个元素,如果它们的顺序不对,就交换它们的位置,直到数组排序完成。
2.插入排序
void insertion_sort(int arr[], int n)
{
for (int i = 1; i < n i int key='arr[i];' int j='i-1;' while j>= 0 && arr[j] > key) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
}
插入排序也是一种基础的排序算法。它的基本思想是将一个元素插入到已经排好序的数组中,一次将一个元素插入到正确的位置。这个算法在处理小型数据集时非常高效。
3.选择排序
void selection_sort(int arr[], int n)
{
for (int i = 0; i < n-1; i++) {
int min_index = i;
for (int j = i+1; j < n; j++) {
if (arr[j] < arr[min_index]) {
min_index = j;
}
}
int temp = arr[i];
arr[i] = arr[min_index];
arr[min_index] = temp;
}
}
选择排序也是一种基础的排序算法。它的基本思想是从未排序的数组中选择最小的元素,将其放在已排序的数组的末尾。这个算法在处理小型数据集时非常高效。
4.快速排序
void quick_sort(int arr[], int low, int high)
{
if (low < high) {
int pivot = partition(arr, low, high);
quick_sort(arr, low, pivot-1);
quick_sort(arr, pivot+1, high);
}
}
int partition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i+1];
arr[i+1] = arr[high];
arr[high] = temp;
return i+1;
}
快速排序是一种高效的排序算法,它的基本思想是选取一个元素作为分区点,将数组分为左右两部分,左部分的元素都小于等于分区点,右部分的元素都大于等于分区点。然后递归地对左右两部分进行快速排序。
5.归并排序
void merge_sort(int arr[], int left, int right)
{
if (left < right) {
int mid = (left + right) / 2;
merge_sort(arr, left, mid);
merge_sort(arr, mid+1, right);
merge(arr, left, mid, right);
}
}
void merge(int arr[], int left, int mid, int right)
{
int i, j, k;
int n1 = mid - left + 1;
int n2 = right - mid;
int L[n1], R[n2];
for (i = 0; i < n1; i++) {
L[i] = arr[left + i];
}
for (j = 0; j < n2; j++) {
R[j] = arr[mid + 1 + j];
}
i = 0;
j = 0;
k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
归并排序是一种稳定的排序算法,它的基本思想是将一个数组分成两个子数组,递归地对子数组进行排序,然后将两个子数组合并为一个有序数组。归并排序通常比快速排序慢,但是它能够处理大型数据集。
6.堆排序
void heap_sort(int arr[], int n)
{
for (int i = n/2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
for (int i = n-1; i > 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}
void heapify(int arr[], int n, int i)
{
int largest = i;
int left = 2*i + 1;
int right = 2*i + 2;
if (left < n arrleft> arr[largest]) {
largest = left;
}
if (right < n arrright> arr[largest]) {
largest = right;
}
if (largest != i) {
int temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
heapify(arr, n, largest);
}
}
堆排序是一种高效的排序算法,它的基本思想是将一个数组看成一个完全二叉树,然后将这个完全二叉树转换成一个堆,递归进行调整,最终得到一个有序数组。堆排序的时间复杂度为O(n log n),空间复杂度为O(1)。
7.计数排序
void counting_sort(int arr[], int n)
{
int max = arr[0];
for (int i = 1; i < n i if arri> max) {
max = arr[i];
}
}
int count[max+1];
for (int i = 0; i <= max; i++) {
count[i] = 0;
}
for (int i = 0; i < n; i++) {
count[arr[i]]++;
}
for (int i = 1; i <= max i counti int outputn for int i='n-1;' i>= 0; i--) {
output[count[arr[i]]-1] = arr[i];
count[arr[i]]--;
}
for (int i = 0; i < n; i++) {
arr[i] = output[i];
}
}
计数排序是一种稳定的排序算法,它的基本思想是统计每个元素出现的次数,然后按照元素的大小顺序将它们放回原数组。计数排序的时间复杂度为O(n+k),其中k是元素的范围,空间复杂度为O(n+k)。
8.桶排序
void bucket_sort(int arr[], int n, int bucket_size)
{
int max = arr[0];
int min = arr[0];
for (int i = 1; i < n i if arri> max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
int bucket_count = (max - min) / bucket_size + 1;
int *buckets[bucket_count];
for (int i = 0; i < bucket_count; i++) {
buckets[i] = (int*)malloc(bucket_size * sizeof(int));
}
for (int i = 0; i < bucket_count; i++) {
int index = 0;
for (int j = 0; j < n j if arrj>= min + i * bucket_size && arr[j] < min + (i+1) * bucket_size) {
buckets[i][index++] = arr[j];
}
}
insertion_sort(buckets[i], index);
}
int index = 0;
for (int i = 0; i < bucket_count; i++) {
for (int j = 0; j < index; j++) {
arr[index++] = buckets[i][j];
}
}
for (int i = 0; i < bucket_count; i++) {
free(buckets[i]);
}
}
桶排序是一种稳定的排序算法,它的基本思想是将一个区间划分为若干个桶,然后将元素放入相应的桶中,对每个桶进行排序,最后将桶中的元素按照顺序合并为一个有序数组。
9.基数排序
void radix_sort(int arr[], int n)
{
int max = arr[0];
for (int i = 1; i < n i if arri> max) {
max = arr[i];
}
}
for (int exp = 1; max/exp > 0; exp *= 10) {
int output[n];
int count[10] = {0};
for (int i = 0; i < n; i++) {
count[(arr[i]/exp)%10]++;
}
for (int i = 1; i < 10 i counti for int i='n-1;' i>= 0; i--) {
output[count[(arr[i]/exp)%10]-1] = arr[i];
count[(arr[i]/exp)%10]--;
}
for (int i = 0; i < n; i++) {
arr[i] = output[i];
}
}
}
基数排序是一种稳定的排序算法,它的基本思想是将整数按照位数进行分解,从低位到高位依次进行排序,最终得到一个有序数组。基数排序的时间复杂度为O(d(n+k)),其中d是位数,k是基数,空间复杂度为O(n+k)。
10.摇摆排序
void wiggle_sort(int arr[], int n)
{
for (int i = 0; i < n-1 i if i 2='= 0)' if arri> arr[i+1]) {
swap(&arr[i], &arr[i+1]);
}
} else {
if (arr[i] < arr[i+1]) {
swap(&arr[i], &arr[i+1]);
}
}
}
}
摇摆排序是一种特殊的排序算法,它的基本思想是将数组元素按照摇摆的方式排列,即将相邻的元素交换,使得它们满足一定的条件。摇摆排序的时间复杂度为O(n),空间复杂度为O(1)。
11.希尔排序
void shell_sort(int arr[], int n)
{
for (int gap = n/2; gap > 0; gap /= 2) {
for (int i = gap; i < n i int temp='arr[i];' int j for j='i;' j>= gap && arr[j-gap] > temp; j -= gap) {
arr[j] = arr[j-gap];
}
arr[j] = temp;
}
}
}
希尔排序是一种改进的插入排序算法,它的基本思想是将数组元素按照一定的间隔分组,对每组进行插入排序,然后逐步缩小间隔,最终得到一个有序数组。希尔排序的时间复杂度为O(n log n),空间复杂度为O(1)。