关于十大算法的介绍参考十大经典排序算法-CSDN博客链接,本文直接用c语言实现十大经典算法。
1.选择排序
以下是选择排序的 C 语言实现代码:
#include <stdio.h>
void selection_sort(int arr[], int n) {
int i, j, min_idx;
// One by one move boundary of unsorted subarray
for (i = 0; i < n-1; i++) {
// Find the minimum element in unsorted array
min_idx = i;
for (j = i+1; j < n; j++) {
if (arr[j] < arr[min_idx]) {
min_idx = j;
}
}
// Swap the found minimum element with the first element
int temp = arr[min_idx];
arr[min_idx] = arr[i];
arr[i] = temp;
}
}
int main() {
int arr[] = {64, 25, 12, 22, 11};
int n = sizeof(arr)/sizeof(arr[0]);
selection_sort(arr, n);
printf("Sorted array: \n");
for (int i=0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
选择排序的思路是在未排序的元素中找到最小(或最大)的元素,存放到未排序元素的第一个位置,然后,再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序元素的末尾。以此类推,直到所有元素均排序完毕。
2.插入排序
以下是使用 C 语言实现插入排序的示例代码:
#include <stdio.h>
void insertion_sort(int arr[], int n) {
int i, j, key;
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;
}
}
int main() {
int arr[] = {12, 11, 13, 5, 6};
int n = sizeof(arr) / sizeof(arr[0]);
insertion_sort(arr, n);
printf("Sorted array: ");
for (int i=0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
在上述代码中,我们首先定义了一个 insertion_sort() 函数,该函数使用插入排序算法对给定数组进行排序。该函数的参数包括要排序的数组和数组的大小。在函数内部,我们使用两个嵌套循环。外层循环遍历数组中的元素,内层循环则将当前元素插入到已排序的子数组中。具体来说,内层循环从当前元素的前一个位置开始,向前遍历已排序的元素,并将它们向右移动,直到找到一个比当前元素小的元素或到达已排序子数组的开头。然后,我们将当前元素插入到正确的位置。
在 main() 函数中,我们首先定义了一个要排序的数组和数组的大小。然后,我们调用 insertion_sort() 函数来对数组进行排序。最后,我们使用一个循环遍历已排序的数组,并使用 printf() 函数打印出每个元素的值。
代码的具体操作如下:
- 定义了一个函数
insertion_sort
,接受一个整数数组和它的长度作为参数。 - 在这个函数内部,首先定义了三个整数变量
i
、j
和key
。i
用来作为循环的索引,j
用来在已排序的部分中寻找插入位置,key
则用来保存当前正在处理的元素。 - 外层循环从第二个元素开始,直到最后一个元素。在每次循环中,
key
保存当前正在处理的元素,然后j
从当前位置向前遍历已排序的部分。 - 当找到一个元素大于
key
时,就停止向前遍历,然后将这个元素之后的元素向后移动一位,为key
腾出空间。 - 最后,将
key
插入到正确的位置。 main
函数中,定义了一个需要排序的数组和它的长度。- 调用
insertion_sort
函数来对数组进行排序。 - 之后,用一个循环打印出排序后的数组。
运行这段代码,输出的结果将是:Sorted array: 5 6 11 12 13。
3.冒泡排序
以下是使用C语言实现冒泡排序的示例代码:
#include <stdio.h>
void bubble_sort(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;
}
}
}
}
int main() {
int arr[] = {64, 25, 12, 22, 11};
int n = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, n);
printf("Sorted array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
在上述代码中,我们首先定义了一个bubble_sort()函数,该函数使用冒泡排序算法对给定数组进行排序。该函数的参数包括要排序的数组和数组的大小。在函数内部,我们使用两个嵌套循环。外层循环遍历数组中的元素,内层循环则将当前元素与后面的元素进行比较,并根据需要交换它们的位置。具体来说,内层循环从当前元素的后一个位置开始,向前遍历已排序的元素,并将它们向右移动,直到找到一个比当前元素小的元素或到达已排序子数组的开头。这样,在每一次外层循环之后,最大的元素都会被移动到数组的末尾。
在main()函数中,我们首先定义了一个要排序的数组和数组的大小。然后,我们调用bubble_sort()函数来对数组进行排序。最后,我们使用一个循环遍历已排序的数组,并使用printf()函数打印出每个元素的值。
代码的具体步骤是:
- 定义了一个函数
bubble_sort
,它接受一个整数数组和数组的长度作为参数。 - 在
bubble_sort
函数中,使用了两个嵌套的循环来实现冒泡排序。外层循环控制排序的轮数,内层循环则负责在每一轮中,通过比较和交换相邻的元素,将最大的元素"冒泡"到数组的末尾。 - 在
main
函数中,定义了一个需要排序的数组,并计算了数组的长度。 - 调用了
bubble_sort
函数来对数组进行排序。 - 最后,使用一个循环打印出排序后的数组。
4.希尔排序
希尔排序是一种基于插入排序的算法,通过比较相隔一定距离的元素,使得每次比较能够跨越多个元素,从而快速地将较大或较小的元素移动到序列的一端。以下是一个简单的希尔排序的实现:
#include <stdio.h>
void shell_sort(int arr[], int n) {
int gap, i, j, temp;
for (gap = n / 2; gap > 0; gap /= 2) {
for (i = gap; i < n; i++) {
temp = arr[i];
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
}
int main() {
int arr[] = {12, 34, 54, 2, 3};
int n = sizeof(arr) / sizeof(arr[0]);
shell_sort(arr, n);
printf("Sorted array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
在上述代码中,我们首先定义了一个shell_sort()函数,该函数使用希尔排序算法对给定数组进行排序。该函数的参数包括要排序的数组和数组的大小。在函数内部,我们首先初始化gap为n/2,然后使用一个循环将gap逐渐缩小为1。在每个循环中,我们使用插入排序的思路对相隔gap的元素进行比较和交换。具体来说,我们首先从第gap个元素开始遍历数组,将当前元素保存到temp变量中,然后向前遍历已排序的元素,找到合适的位置将temp插入到数组中。插入完成后,我们将gap缩小一半,并继续进行下一轮循环,直到gap为1。最后,我们再对整个数组进行一次插入排序,以得到最终的排序结果。
在main()函数中,我们首先定义了一个要排序的数组和数组的大小。然后,我们调用shell_sort()函数来对数组进行排序。最后,我们使用一个循环遍历已排序的数组,并使用printf()函数打印出每个元素的值。
具体来说,这段代码的步骤如下:
- 定义一个函数
shell_sort
,接受一个整数数组arr
和数组大小n
作为参数。 - 在
shell_sort
函数内部,首先初始化一个变量gap
为n / 2
,表示初始的间隔。 - 使用一个循环,将
gap
逐渐缩小为1。在每个循环中,使用插入排序的思路对相隔gap
的元素进行比较和交换。 - 在主函数
main
中,定义一个要排序的整数数组arr
和数组大小n
,然后调用shell_sort
函数来对数组进行排序。 - 最后,使用一个循环遍历已排序的数组,并使用
printf
函数打印出每个元素的值。
5.归并排序
以下是使用C语言实现归并排序的示例代码:
#include <stdio.h>
#include <stdlib.h>
// 归并排序函数
void merge_sort(int arr[], int left, int right) {
int i, j, k;
int *temp = (int *)malloc(sizeof(int) * right - left + 1);
// 递归结束条件
if (left >= right) {
return;
}
// 分割数组
i = left;
j = right;
k = 0;
while (i <= j) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
// 合并数组
k = 0;
i = left;
j = right;
while (i <= j) {
if (temp[k] <= arr[i]) {
arr[i++] = temp[k++];
} else if (temp[k] <= arr[j]) {
arr[j--] = temp[k++];
} else {
break;
}
}
// 继续递归排序左右两个子数组
merge_sort(arr, left, j - 1);
merge_sort(arr, j + 1, right);
}
int main() {
int arr[] = {5, 4, 3, 2, 1};
int len = sizeof(arr) / sizeof(arr[0]);
merge_sort(arr, 0, len - 1);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
在这个示例代码中,我们首先定义了一个归并排序函数merge_sort,接受一个整型数组arr、左边界left和右边界right作为参数。如果左边界大于等于右边界,表示数组已经排序完成,直接返回即可。否则,我们递归地将数组分成左右两个子数组,并使用merge_sort函数继续对左右两个子数组进行排序。然后,我们使用一个临时数组temp来存储左右两个子数组中的较小值,并将其合并成一个有序的数组。最后,我们释放临时数组temp的内存空间,并返回排序后的数组。在主函数中,我们定义一个整型数组arr,并使用merge_sort函数对其进行排序。最后,我们打印排序后的数组。
6.快速排序
以下是使用C语言实现快速排序的示例代码:
#include <stdio.h>
void quick_sort(int arr[], int left, int right) {
if (left >= right) {
return;
}
int i = left, j = right, pivot = arr[left];
while (i < j) {
while (i < j && arr[j] >= pivot) {
j--;
}
if (i < j) {
arr[i] = arr[j];
i++;
}
while (i < j && arr[i] <= pivot) {
i++;
}
if (i < j) {
arr[j] = arr[i];
j--;
}
}
arr[i] = pivot;
quick_sort(arr, left, i - 1);
quick_sort(arr, i + 1, right);
}
int main() {
int arr[] = {9, 5, 7, 1, 3, 10, 2, 8, 4, 6};
int n = sizeof(arr) / sizeof(arr[0]);
quick_sort(arr, 0, n - 1);
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
在这个示例代码中,我们定义了一个quick_sort函数来实现快速排序。函数接受一个整型数组、左边界和右边界作为参数。我们首先选择数组的第一个元素作为基准值,并使用双指针法将数组划分为两个部分,左半部分比基准值小,右半部分比基准值大。然后,递归地对左半部分和右半部分进行快速排序,直到排序完成。在main函数中,我们定义了一个整型数组,并使用quick_sort函数对其进行排序,最后输出排序后的数组。
代码的主要步骤:
- 检查待排序数组的长度是否为0或1,如果是则直接返回(因为这样规模的数组已经是有序的)。
- 选择数组的第一个元素作为基准值。
- 从数组的两端开始,如果左端的元素大于基准值,或者右端的元素小于基准值,就交换这两个元素的位置。重复这个过程,直到左指针和右指针相遇。
- 将基准值放到相遇点的位置。
- 对基准值左侧和右侧的两个子数组递归进行上述过程。
7.堆排序
以下是使用C语言实现堆排序的示例代码:
#include <stdio.h>
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 temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
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--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}
void printArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr[] = {12, 11, 13, 5, 6, 7};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Original array: ");
printArray(arr, n);
heapSort(arr, n);
printf("Sorted array: ");
printArray(arr, n);
return 0;
}
堆排序是一种有效的排序方法,其时间复杂度为O(n log n)。该算法首先将数组构建成最大堆,然后通过交换堆顶元素和最后一个元素,并且将堆的大小减一,从而将最大元素移到数组的末尾。这个过程反复进行,直到整个数组被排序。
在代码中,heapify
函数是用来调整堆的,使得父节点大于其子节点,从而保证堆的性质。heapSort
函数首先对数组进行构建堆操作,然后进行排序操作。最后,printArray
函数用于打印数组。
8.计数排序
以下是C语言实现计数排序的示例代码:
#include <stdio.h>
#include <stdlib.h>
#define MAX_VALUE 1000
void countingSort(int arr[], int n) {
int i, j;
int count[MAX_VALUE + 1] = {0};
int output[n]; // 新数组用于保存排序后的结果
// 计算每个元素出现的次数
for (i = 0; i < n; i++) {
count[arr[i]]++;
}
// 将count数组的值转移至output数组
for (i = 1; i <= MAX_VALUE; i++) {
if (count[i] != 0) {
for (j = 0; j < count[i]; j++) {
output[j] = i;
}
}
}
// 将排好序的output数组复制回原数组arr
for (i = 0; i < n; i++) {
arr[i] = output[i];
}
}
int main() {
int arr[] = {3, 2, 1, 5, 4, 2, 6, 3, 2, 1};
int n = sizeof(arr) / sizeof(arr[0]);
int i;
printf("Original array: ");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
countingSort(arr, n);
printf("\nSorted array: ");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
该示例代码中,计数排序的核心实现部分在countingSort
函数中。该函数首先遍历原始数组arr
,统计每个元素出现的次数,保存在count
数组中。然后,从最小的数1开始,依次将count
数组中对应于每个数出现的次数进行累加,将每个数出现的次数减一,并将该数添加到新的数组中。最后,返回排好序的新数组。
在主函数中,首先定义了一个原始数组arr
,并初始化。然后,通过调用countingSort
函数对该数组进行排序,并输出原始数组和排序后的数组。
9.桶排序
桶排序(Bucket Sort)是一种线性排序算法,适用于待排序数据均匀分布在一个固定范围内的情况。其基本思想是将待排序数据分配到一个有限数量的桶中,然后对每个桶中的数据进行排序,最后按照桶的顺序依次输出所有元素。以下是使用 C 语言实现桶排序的代码示例:
#include <stdio.h>
#include <stdlib.h>;
#define MAX_VALUE 1000
void bucketSort(int arr[], int n) {
int i, j, max_val = 0;
int *bucket;
// 找到最大值,确定桶的数量
for (i = 0; i < n; i++) {
if (arr[i] > max_val) {
max_val = arr[i];
}
}
// 分配桶
bucket = (int *)calloc(max_val + 1, sizeof(int));
// 将元素分配到桶中
for (i = 0; i < n; i++) {
bucket[arr[i]]++;
}
// 对每个桶中的元素进行排序,并输出结果
for (i = 0; i <= max_val; i++) {
for (j = 0; j < bucket[i]; j++) {
printf("%d ", i);
}
}
free(bucket);
}
int main() {
int arr[] = {3, 2, 1, 5, 4, 2, 6, 3, 2, 1};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Original array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
bucketSort(arr, n);
return 0;
}
在这个实现中,我们首先找到待排序数组中的最大值,并根据最大值创建了一个桶数组。接下来,我们将每个元素插入到对应的桶中。最后,对每个桶中的元素进行排序,并按照桶的顺序输出所有元素。需要注意的是,这里的排序算法可以使用各种不同的排序算法实现,例如插入排序、快速排序等。
10.基数排序
基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。下面是一个用 C 语言实现基数排序的简单示例:
#include <stdio.h>
#include <stdlib.h>
#define MAX_LEN 100
// 按从低位到高位的顺序进行排序
void radixsort(int *arr, int n) {
int i, max_val = 0;
int *tmp = (int *)malloc(sizeof(int) * n);
for (i = 0; i < n; i++) {
if (arr[i] > max_val) {
max_val = arr[i];
}
}
int *bucket = (int *)calloc(max_val + 1, sizeof(int));
for (i = 1, max_val >>= 1; i <= 32; i <<= 1, max_val >>= 1) {
int j, sum = 0;
for (j = 0; j <= max_val; j++) {
bucket[j] = 0;
}
for (j = 0; j < n; j++) {
bucket[((arr[j] >> i) & 1) + sum]++;
}
for (j = 1; j <= max_val; j++) {
tmp[bucket[j] - 1] = ((j + sum) << i) | (arr[bucket[j] - 1] & ((1 << i) - 1));
}
for (j = 0; j < n; j++) {
arr[j] = tmp[j];
}
}
free(tmp);
free(bucket);
}
int main() {
int arr[] = {170, 45, 75, 90, 802, 24, 2, 66};
int n = sizeof(arr) / sizeof(arr[0]);
radixsort(arr, n);
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
在这个示例中,我们首先找到待排序数组中的最大值,并使用一个 bucket 数组来记录每个数字出现的次数。然后我们从低位到高位对每个数字进行排序,将结果保存在一个临时数组中,最后将临时数组中的结果复制回原数组。这个过程重复进行,直到所有位数都被处理完为止。