当前位置: 首页 > news >正文

C语言练习百题之排序算法

题目:C语言实现排序算法

冒泡排序

思路:

  • 依次比较相邻的元素,如果顺序不对则交换,直到整个数组有序。

实现代码:

#include <stdio.h>void bubbleSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90, 87, 10, 5};int n = sizeof(arr) / sizeof(arr[0]);bubbleSort(arr, n);printf("排序后的数组: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);return 0;
}

优缺点:

  • 优点:实现简单。
  • 缺点:对于大规模数据排序效率低,时间复杂度为O(n^2)。

选择排序

思路:

  • 从未排序的部分选择最小元素,与未排序部分的第一个元素交换位置。
  • 重复这个过程,直到整个数组有序。

实现代码:

#include <stdio.h>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;}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90, 87, 10, 5};int n = sizeof(arr) / sizeof(arr[0]);selectionSort(arr, n);printf("排序后的数组: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);return 0;
}

优缺点:

  • 优点:实现简单。
  • 缺点:对于大规模数据排序效率低,时间复杂度为O(n^2)。

插入排序

思路:

  • 将数组分为已排序和未排序两部分,逐步将未排序的元素插入到已排序的部分,直到整个数组有序。

实现代码:

#include <stdio.h>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;}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90, 87, 10, 5};int n = sizeof(arr) / sizeof(arr[0]);insertionSort(arr, n);printf("排序后的数组: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);return 0;
}

优缺点:

  • 优点:简单,对小规模数据或接近有序的数据排序效率高。
  • 缺点:对于大规模数据排序效率低,时间复杂度为O(n^2)。

归并排序

思路:

  • 将数组递归分成子数组,然后合并这些子数组,合并过程中保持有序。

实现代码:

#include <stdio.h>
#include <stdlib.h>void merge(int arr[], int left, int middle, int right) {int n1 = middle - left + 1;int n2 = right - middle;int L[n1], R[n2];for (int i = 0; i < n1; i++)L[i] = arr[left + i];for (int j = 0; j < n2; j++)R[j] = arr[middle + 1 + j];int 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++;}
}void mergeSort(int arr[], int left, int right) {if (left < right) {int middle = left + (right - left) / 2;mergeSort(arr, left, middle);mergeSort(arr, middle + 1, right);merge(arr, left, middle, right);}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90, 87, 10, 5};int n = sizeof(arr) / sizeof(arr[0]);mergeSort(arr, 0, n - 1);printf("排序后的数组: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);return 0;
}

优缺点:

  • 优点:稳定,时间复杂度为O(n log n)。
  • 缺点:需要额外的内存空间。

快速排序

思路:

  • 选择一个基准元素,将数组分为小于基准和大于基准的两部分,然后递归地对这两部分进行排序。

实现代码:

#include <stdio.h>void swap(int* a, int* b) {int t = *a;*a = *b;*b = t;
}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++;swap(&arr[i], &arr[j]);}}swap(&arr[i + 1], &arr[high]);return i + 1;
}void quickSort(int arr[], int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90, 87, 10, 5};int n = sizeof(arr) / sizeof(arr[0]);quickSort(arr, 0, n - 1);printf("排序后的数组: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);return 0;
}

优缺点:

  • 优点:效率高,时间复杂度平均情况下为O(n log n)。
  • 缺点:不稳定。

希尔排序

思路:

  • 将数组按一定间隔分组,对每组使用插入排序。
  • 缩小间隔,重复上述步骤,直到间隔为1,进行最后一次插入排序。

实现代码:

#include <stdio.h>void shellSort(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;}}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90, 87, 10, 5};int n = sizeof(arr) / sizeof(arr[0]);shellSort(arr, n);printf("排序后的数组: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);return 0;
}

优缺点:

  • 优点:相对于简单排序算法有较高的效率,时间复杂度受增量序列的影响。
  • 缺点:不稳定。

堆排序

思路:

  • 构建最大堆(或最小堆),将堆顶元素与最后一个元素交换,然后将堆的大小减一并重新维护堆的性质。
  • 重复此过程,直到堆为空,得到有序数组。

实现代码:

#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);}
}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90, 87, 10, 5};int n = sizeof(arr) / sizeof(arr[0]);heapSort(arr, n);printf("排序后的数组: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);return 0;
}

优缺点:

  • 优点:高效的原地排序算法,时间复杂度为O(n log n)。
  • 缺点:不稳定。

计数排序

思路:

  • 统计数组中每个元素的出现次数,然后根据元素值和出现次数重新构建数组。

实现代码:

#include <stdio.h>
#include <stdlib.h>void countSort(int arr[], int n) {int max = arr[0];for (int i = 1; i < n; i++) {if (arr[i] > max)max = arr[i];}int* count = (int*)malloc((max + 1) * sizeof(int));int* output = (int*)malloc(n * sizeof(int));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++)count[i] += count[i - 1];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];free(count);free(output);
}int main() {int arr[] = {4, 2, 2, 8, 3, 3, 1, 5, 9};int n = sizeof(arr) / sizeof(arr[0]);countSort(arr, n);printf("排序后的数组: ");for (int i = 0; i < n; i++)printf("%d ", arr[i]);return 0;
}

优缺点:

  • 优点:适用于元素范围不大的情况,时间复杂度为O(n + k),k为最大元素值。
  • 缺点:对于元素范围很大的数据效率较低。

总结和推荐

  • 推荐的排序算法:归并排序和快速排序
  • 归并排序和快速排序都是高效的排序算法,时间复杂度为O(n log n),适用于各种规模的数据集。
  • 归并排序是稳定的,但需要额外的内存空间,适用于所有数据类型。
  • 快速排序是不稳定的,但在实践中通常比归并排序更快,适用于大规模数据集。

这里推荐归并排序作为首选,因为它是稳定的且不会对原始数据造成修改。如果在内存受限的情况下考虑,可以选择快速排序。Bubble Sort、Selection Sort 和 Insertion Sort 适用于小规模数据集或教学目的,不推荐用于实际应用。

http://www.lryc.cn/news/185335.html

相关文章:

  • 通过ElementUi在Vue搭建的项目中实现CRUD
  • 【CSS如何进行圣杯布局】
  • flex 实现的圣杯布局
  • 数字人直播软件排名推荐,铭顺科技数字人品牌抢占“日不落”流量新技能
  • 【AI视野·今日Robot 机器人论文速览 第四十五期】Mon, 2 Oct 2023
  • 【计算机网络】网络编程接口 Socket API 解读(9)
  • 用户端App自动化测试
  • [洛谷]P2697 宝石串(经典好题!)
  • 毫米波汽车雷达测试应用指南
  • 抖音账号矩阵系统开发源码----技术研发
  • C++ 33.学习C++的意义-狄泰软件学院
  • [C++基础]-多态
  • 【Kubernetes】当K8s出现问题时,我们可以从哪些方面排查出
  • SentenceTransformer 之论文解读
  • AI发展历史
  • 想要精通算法和SQL的成长之路 - 简化路径
  • 【哈士奇赠书活动 - 41期】- 〖产品设计软技能:创业公司篇〗
  • MARS: An Instance-aware, Modular and Realistic Simulator for Autonomous Driving
  • 关联规则挖掘(上):数据分析 | 数据挖掘 | 十大算法之一
  • centos7 + citus12 + postgresql 14 安装
  • MySQL、Oracle、SQL Server / MS Access 中的 NULL函数用法
  • App Store审核被拒原因与解决方案
  • ​LeetCode解法汇总121. 买卖股票的最佳时机
  • 【Go】go-es统计接口被刷数和ip访问来源
  • debian 安装 pg --chatGpt
  • 商城小程序代客下单程序开发演示
  • SpringBoot 整合 jetcache缓存
  • HTML5+CSS3+移动web 前端开发入门笔记(二)HTML标签详解
  • Maven 配置阿里云镜像
  • 矢量图绘制软件EazyDraw mac中文版软件介绍