c语言算法编程练习

关于十大算法的介绍参考十大经典排序算法-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() 函数打印出每个元素的值。

代码的具体操作如下:

  1. 定义了一个函数insertion_sort,接受一个整数数组和它的长度作为参数。
  2. 在这个函数内部,首先定义了三个整数变量ijkeyi用来作为循环的索引,j用来在已排序的部分中寻找插入位置,key则用来保存当前正在处理的元素。
  3. 外层循环从第二个元素开始,直到最后一个元素。在每次循环中,key保存当前正在处理的元素,然后j从当前位置向前遍历已排序的部分。
  4. 当找到一个元素大于key时,就停止向前遍历,然后将这个元素之后的元素向后移动一位,为key腾出空间。
  5. 最后,将key插入到正确的位置。
  6. main函数中,定义了一个需要排序的数组和它的长度。
  7. 调用insertion_sort函数来对数组进行排序。
  8. 之后,用一个循环打印出排序后的数组。

运行这段代码,输出的结果将是: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()函数打印出每个元素的值。

代码的具体步骤是:

  1. 定义了一个函数bubble_sort,它接受一个整数数组和数组的长度作为参数。
  2. bubble_sort函数中,使用了两个嵌套的循环来实现冒泡排序。外层循环控制排序的轮数,内层循环则负责在每一轮中,通过比较和交换相邻的元素,将最大的元素"冒泡"到数组的末尾。
  3. main函数中,定义了一个需要排序的数组,并计算了数组的长度。
  4. 调用了bubble_sort函数来对数组进行排序。
  5. 最后,使用一个循环打印出排序后的数组。

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()函数打印出每个元素的值。

具体来说,这段代码的步骤如下:

  1. 定义一个函数shell_sort,接受一个整数数组arr和数组大小n作为参数。
  2. shell_sort函数内部,首先初始化一个变量gapn / 2,表示初始的间隔。
  3. 使用一个循环,将gap逐渐缩小为1。在每个循环中,使用插入排序的思路对相隔gap的元素进行比较和交换。
  4. 在主函数main中,定义一个要排序的整数数组arr和数组大小n,然后调用shell_sort函数来对数组进行排序。
  5. 最后,使用一个循环遍历已排序的数组,并使用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函数对其进行排序,最后输出排序后的数组。

代码的主要步骤:

  1. 检查待排序数组的长度是否为0或1,如果是则直接返回(因为这样规模的数组已经是有序的)。
  2. 选择数组的第一个元素作为基准值。
  3. 从数组的两端开始,如果左端的元素大于基准值,或者右端的元素小于基准值,就交换这两个元素的位置。重复这个过程,直到左指针和右指针相遇。
  4. 将基准值放到相遇点的位置。
  5. 对基准值左侧和右侧的两个子数组递归进行上述过程。

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 数组来记录每个数字出现的次数。然后我们从低位到高位对每个数字进行排序,将结果保存在一个临时数组中,最后将临时数组中的结果复制回原数组。这个过程重复进行,直到所有位数都被处理完为止。

猜你喜欢

转载自blog.csdn.net/tombaby_come/article/details/133860581