揭秘C语言数组排序技巧:16种高效算法实战解析

排序算法是计算机科学中的一项基本技能,而在C语言编程中,数组排序是实现这一技能的常用方式。本文将详细介绍16种常见的排序算法,并通过C语言代码实例进行实战解析,帮助读者深入了解每种算法的原理和实现。

1. 冒泡排序(Bubble Sort)

冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复地进行,直到没有再需要交换的元素为止。

void bubbleSort(int arr[], int n) {

int i, j, temp;

for (i = 0; i < n - 1; i++) {

for (j = 0; j < n - i - 1; j++) {

if (arr[j] > arr[j + 1]) {

temp = arr[j];

arr[j] = arr[j + 1];

arr[j + 1] = temp;

}

}

}

}

2. 选择排序(Selection Sort)

选择排序是一种简单直观的排序算法。它的工作原理是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

void selectionSort(int arr[], int n) {

int i, j, min_idx, temp;

for (i = 0; i < n - 1; i++) {

min_idx = i;

for (j = i + 1; j < n; j++) {

if (arr[j] < arr[min_idx]) {

min_idx = j;

}

}

temp = arr[min_idx];

arr[min_idx] = arr[i];

arr[i] = temp;

}

}

3. 插入排序(Insertion Sort)

插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

void insertionSort(int arr[], int n) {

int i, key, j;

for (i = 1; i < n; i++) {

key = arr[i];

j = i - 1;

while (j >= 0 && arr[j] > key) {

arr[j + 1] = arr[j];

j = j - 1;

}

arr[j + 1] = key;

}

}

4. 快速排序(Quick Sort)

快速排序是C语言中常用的一种排序算法,采用分而治之的策略,将大问题分解为小问题来解决。

void quickSort(int arr[], int left, int right) {

int i = left, j = right;

int tmp;

int pivot = arr[(left + right) / 2];

/* partition */

while (i <= j) {

while (arr[i] < pivot)

i++;

while (arr[j] > pivot)

j--;

if (i <= j) {

tmp = arr[i];

arr[i] = arr[j];

arr[j] = tmp;

i++;

j--;

}

};

/* recursion */

if (left < j)

quickSort(arr, left, j);

if (i < right)

quickSort(arr, i, right);

}

5. 归并排序(Merge Sort)

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用。

void merge(int arr[], int l, int m, int r) {

int i, j, k;

int n1 = m - l + 1;

int n2 = r - m;

/* create temp arrays */

int L[n1], R[n2];

/* Copy data to temp arrays L[] and R[] */

for (i = 0; i < n1; i++)

L[i] = arr[l + i];

for (j = 0; j < n2; j++)

R[j] = arr[m + 1 + j];

/* Merge the temp arrays back into arr[l..r]*/

i = 0;

j = 0;

k = l;

while (i < n1 && j < n2) {

if (L[i] <= R[j]) {

arr[k] = L[i];

i++;

} else {

arr[k] = R[j];

j++;

}

k++;

}

/* Copy the remaining elements of L[], if there are any */

while (i < n1) {

arr[k] = L[i];

i++;

k++;

}

/* Copy the remaining elements of R[], if there are any */

while (j < n2) {

arr[k] = R[j];

j++;

k++;

}

}

void mergeSort(int arr[], int l, int r) {

if (l < r) {

int m = l + (r - l) / 2;

mergeSort(arr, l, m);

mergeSort(arr, m + 1, r);

merge(arr, l, m, r);

}

}

6. 希尔排序(Shell Sort)

希尔排序是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。

void shellSort(int arr[], int n) {

int gap = n / 2;

while (gap > 0) {

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;

}

gap /= 2;

}

}

7. 计数排序(Counting Sort)

计数排序是一种非比较型整数排序算法,其原理是将输入数据分成有序和无序两部分,然后对无序部分进行排序。

void countingSort(int arr[], int n) {

int max = arr[0];

for (int i = 1; i < n; i++) {

if (arr[i] > max) {

max = arr[i];

}

}

int range = max + 1;

int* count = (int*)calloc(range, sizeof(int));

for (int i = 0; i < n; i++) {

count[arr[i]]++;

}

int index = 0;

for (int i = 0; i < range; i++) {

while (count[i] > 0) {

arr[index++] = i;

count[i]--;

}

}

free(count);

}

8. 堆排序(Heap Sort)

堆排序是一种基于比较的排序算法。它使用堆这种数据结构所设计的一种排序算法。

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) {

swap(&arr[i], &arr[largest]);

heapify(arr, n, largest);

}

}

void heapSort(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--) {

swap(&arr[0], &arr[i]);

heapify(arr, i, 0);

}

}

9. 桶排序(Bucket Sort)

桶排序是一个非比较排序算法,其原理是将数组分到有限数量的桶里,每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。

void bucketSort(int arr[], int n) {

float max = arr[0];

for (int i = 1; i < n; i++)

if (arr[i] > max)

max = arr[i];

int numBuckets = (int)(max / (n / 10) + 1);

int* buckets = (int*)calloc(numBuckets, sizeof(int));

for (int i = 0; i < n; i++)

buckets[arr[i] / (n / 10)]++;

int index = 0;

for (int i = 0; i < numBuckets; i++) {

while (buckets[i] > 0) {

arr[index++] = i * (n / 10);

buckets[i]--;

}

}

free(buckets);

}

10. 基数排序(Radix Sort)

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数进行比较排序。

void countingSortForRadix(int arr[], int size, int position) {

int* output = (int*)calloc(size, sizeof(int));

int* count = (int*)calloc(10, sizeof(int));

for (int i = 0; i < size; i++)

count[(arr[i] / position) % 10]++;

for (int i = 1; i < 10; i++)

count[i] += count[i - 1];

for (int i = size - 1; i >= 0; i--) {

output[count[(arr[i] / position) % 10] - 1] = arr[i];

count[(arr[i] / position) % 10]--;

}

for (int i = 0; i < size; i++)

arr[i] = output[i];

free(output);

free(count);

}

void radixSort(int arr[], int size) {

int max = arr[0];

for (int i = 1; i < size; i++)

if (arr[i] > max)

max = arr[i];

for (int position = 1; max / position > 0; position *= 10)

countingSortForRadix(arr, size, position);

}

11. 希尔-玛瑟排序(Shell-Mars Sort)

希尔-玛瑟排序是希尔排序和冒泡排序的混合体,它首先将整个数组分成多个子数组,然后对每个子数组进行冒泡排序,最后对整个数组进行一次冒泡排序。

void shellMarsSort(int arr[], int n) {

int gap = n / 2;

while (gap > 0) {

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;

}

gap /= 2;

}

for (int i = 0; i < n - 1; i++) {

if (arr[i] > arr[i + 1]) {

int temp = arr[i];

arr[i] = arr[i + 1];

arr[i + 1] = temp;

}

}

}

12. 旋转排序(Gnome Sort)

旋转排序是一种简单直观的排序算法。它的工作原理是:将一个元素与它前面的元素进行比较,如果它们是逆序的,则交换它们的位置。

void gnomeSort(int arr[], int n) {

int index = 0;

while (index < n) {

if (index == 0)

index++;

if (arr[index] >= arr[index - 1]) {

index++;

} else {

int temp = arr[index];

arr[index] = arr[index - 1];

arr[index - 1] = temp;

index--;

}

}

}

13. 稳定归并排序(Stable Merge Sort)

稳定归并排序是归并排序的一个变种,它保证了相同元素的相对顺序。

void stableMergeSort(int arr[], int l, int r) {

if (l < r) {

int m = l + (r - l) / 2;

stableMergeSort(arr, l, m);

stableMergeSort(arr, m + 1, r);

merge(arr, l, m, r);

}

}

14. 堆排序(Heap Sort)

堆排序是一种基于比较的排序算法,它使用堆这种数据结构所设计的一种排序算法。

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) {

swap(&arr[i], &arr[largest]);

heapify(arr, n, largest);

}

}

void heapSort(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--) {

swap(&arr[0], &arr[i]);

heapify(arr, i, 0);

}

}

15. 桶排序(Bucket Sort)

桶排序是一种非比较排序算法,其原理是将数组分到有限数量的桶里,每个桶再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。

void countingSortForRadix(int arr[], int size, int position) {

int* output = (int*)calloc(size, sizeof(int));

int* count = (int*)calloc(10, sizeof(int));

for (int i = 0; i < size; i++)

count[(arr[i] / position) % 10]++;

for (int i = 1; i < 10; i++)

count[i] += count[i - 1];

for (int i = size - 1; i >= 0; i--) {

output[count[(arr[i] / position) % 10] - 1] = arr[i];

count[(arr[i] / position) % 10]--;

}

for (int i = 0; i < size; i++)

arr[i] = output[i];

free(output);

free(count);

}

void radixSort(int arr[], int size) {

int max = arr[0];

for (int i = 1; i < size; i++)

if (arr[i] > max)

max = arr[i];

for (int position = 1; max / position > 0; position *= 10)

countingSortForRadix(arr, size, position);

}

16. 基数排序(Radix Sort)

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数进行比较排序。

void countingSortForRadix(int arr[], int size, int position) {

int* output = (int*)calloc(size, sizeof(int));

int* count = (int*)calloc(10, sizeof(int));

for (int i = 0; i < size; i++)

count[(arr[i] / position) % 10]++;

for (int i = 1; i < 10; i++)

count[i] += count[i - 1];

for (int i = size - 1; i >= 0; i--) {

output[count[(arr[i] / position) % 10] - 1] = arr[i];

count[(arr[i] / position) % 10]--;

}

for (int i = 0; i < size; i++)

arr[i] = output[i];

free(output);

free(count);

}

void radixSort(int arr[], int size) {

int max = arr[0];

for (int i = 1; i < size; i++)

if (arr[i] > max)

max = arr[i];

for (int position = 1; max / position > 0; position *= 10)

countingSortForRadix(arr, size, position);

}

通过以上16种排序算法的实战解析,读者可以了解到C语言中常见的排序算法及其实现原理。在实际应用中,可以根据具体需求和数据特点选择合适的排序算法,以达到最佳的性能。

[an error occurred while processing the directive]