您现在的位置是:首页 >技术教程 >【C语言】十大经典排序代码及GIF演示网站首页技术教程
【C语言】十大经典排序代码及GIF演示
🔥🔥🔥专栏推荐:C语言基础语法🔥🔥🔥
1. 冒泡排序
- 通过依次比较相邻的两个元素,将较大(小)的元素向后(前)移动,实现排序。时间复杂度为O(n2),空间复杂度为O(1),适用于数据量较小的排序。
void bubbleSort(int arr[], int n) {
int i, j;
for (i = 0; i < n-1; i++) {
for (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;
}
}
}
}
冒泡排序对{8,5,3,6,9,10,2,1,0,4,7}进行排序
排序过程展示:
第一轮:
8,5,3,6,9,2,1,0,4,7,10
第二轮:
5,3,6,8,2,1,0,4,7,9,10
第三轮:
3,5,6,2,1,0,4,7,8,9,10
第四轮:
3,5,2,1,0,4,6,7,8,9,10
第五轮:
3,2,1,0,4,5,6,7,8,9,10
第六轮:
2,1,0,3,4,5,6,7,8,9,10
第七轮:
1,0,2,3,4,5,6,7,8,9,10
第八轮:
0,1,2,3,4,5,6,7,8,9,10
- 优点:简单易懂,代码实现容易。
- 缺点:效率较低,时间复杂度为O(n2)。
- 时间复杂度:最好情况O(n),最坏情况O(n2),平均情况O(n2)。
- 空间复杂度:O(1)。
- 适用范围:数据规模较小的情况下。
- 实际应用实例:对学生按照成绩进行排序。
2. 选择排序
- 从未排序的序列中选择最小(大)的元素,放到已排序的序列的末尾,实现排序。时间复杂度为O(n2),空间复杂度为O(1),适用于数据量较小的排序。
void selectionSort(int arr[], int n) {
int i, j, min_idx;
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;
}
}
int temp = arr[i];
arr[i] = arr[min_idx];
arr[min_idx] = temp;
}
}
选择排序对{8,5,3,6,9,10,2,1,0,4,7}进行排序
排序过程展示:
第一轮:
0,5,3,6,9,10,2,1,8,4,7
第二轮:
0,1,3,6,9,10,2,5,8,4,7
第三轮:
0,1,2,6,9,10,3,5,8,4,7
第四轮:
0,1,2,3,9,10,6,5,8,4,7
第五轮:
0,1,2,3,4,10,6,5,8,9,7
第六轮:
0,1,2,3,4,5,6,10,8,9,7
第七轮:
0,1,2,3,4,5,6,7,8,9,10
- 优点:比冒泡排序更快,实现简单。
- 缺点:效率仍然较低,不稳定。
- 时间复杂度:最好情况O(n2),最坏情况O(n2),平均情况O(n2)。
- 空间复杂度:O(1)。
- 适用范围:数据规模较小的情况下。
- 实际应用实例:对商品按照价格进行排序。
3. 插入排序
- 将未排序的元素插入到已排序的序列中,实现排序。时间复杂度为O(n2),空间复杂度为O(1),适用于数据量较小且基本有序的排序。
void insertionSort(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--;
}
arr[j+1] = key;
}
}
插入排序对{8,5,3,6,9,10,2,1,0,4,7}进行排序
排序过程展示:
第一轮:
5,8,3,6,9,10,2,1,0,4,7
第二轮:
3,5,8,6,9,10,2,1,0,4,7
第三轮:
3,5,6,8,9,10,2,1,0,4,7
第四轮:
2,3,5,6,8,9,10,1,0,4,7
第五轮:
1,2,3,5,6,8,9,10,0,4,7
第六轮:
0,1,2,3,5,6,8,9,10,4,7
第七轮:
0,1,2,3,4,5,6,8,9,10,7
第八轮:
0,1,2,3,4,5,6,7,8,9,10
- 优点:对于小规模数据排序效率高,稳定。
- 缺点:数据规模较大时效率明显下降。
- 时间复杂度:最好情况O(n),最坏情况O(n2),平均情况O(n2)。
- 空间复杂度:O(1)。
- 适用范围:数据规模较小的情况下。
- 实际应用实例:对一段英文文本进行排序。
4. 快速排序
- 通过选定一个基准元素,将序列分为左右两个部分,左边的元素都小于(大于)基准元素,右边的元素都大于(小于)基准元素,递归实现排序。时间复杂度为O(nlogn),空间复杂度为O(logn),适用于大数据量的排序。
void quickSort(int arr[], int low, int high) {
if (low < high) {
int pivot = arr[high];
int i = low - 1;
int j;
for (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;
int pi = i + 1;
quickSort(arr, low, pi-1);
quickSort(arr, pi+1, high);
}
}
快速排序对{8,5,3,6,9,10,2,1,0,4,7}进行排序
排序过程展示:
第一轮:
4,5,3,6,9,10,2,1,0,8,7
第二轮:
0,1,2,3,4,5,6,9,8,10,7
第三轮:
0,1,2,3,4,5,6,7,8,10,9
- 优点:效率高,是所有O(nlogn)排序中最快的。
- 缺点:不稳定,对于数据规模较小的情况下效率不如插入排序。
- 时间复杂度:最好情况O(nlogn),最坏情况O(n2),平均情况O(nlogn)。
- 空间复杂度:最好情况O(logn),最坏情况O(n),平均情况O(logn)。
- 适用范围:数据规模较大的情况下,排序效率高。
- 实际应用实例:对大规模数据进行排序。
5. 归并排序
- 将序列分为若干个子序列,将相邻的子序列进行合并,递归实现排序。时间复杂度为O(nlogn),空间复杂度为O(n),适用于大数据量的排序。
void merge(int arr[], int l, int m, int r) {
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
int L[n1], R[n2];
for (i = 0; i < n1; i++) {
L[i] = arr[l + i];
}
for (j = 0; j < n2; j++) {
R[j] = arr[m + 1 + j];
}
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++;
}
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
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);
}
}
归并排序对{8,5,3,6,9,10,2,1,0,4,7}进行排序
排序过程展示:
第一轮:
3,5,6,8,9,10,0,1,2,4,7
第二轮:
0,1,2,3,4,5,6,7,8,9,10
- 优点:效率高,稳定。
- 缺点:空间复杂度较高。
- 时间复杂度:最好情况O(nlogn),最坏情况O(nlogn),平均情况O(nlogn)。
- 空间复杂度:O(n)。
- 适用范围:数据规模较大的情况下,排序效率高。
- 实际应用实例:对大规模数据进行排序。
6. 堆排序
- 将序列构建成一个堆,将堆顶元素取出放到已排序的序列的末尾,然后重新调整堆,递归实现排序。时间复杂度为O(nlogn),空间复杂度为O(1),适用于大数据量的排序。
void heapify(int arr[], int n, int i) {
int largest = i;
int l = 2*i + 1;
int r = 2*i + 2;
if (l < n && arr[l] > arr[largest]) {
largest = l;
}
if (r < n && arr[r] > arr[largest]) {
largest = r;
}
if (largest != i) {
int temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
heapify(arr, n, largest);
}
}
void heapSort(int arr[], int n) {
int i;
for (i = n/2-1; i >= 0; i--) {
heapify(arr, n, i);
}
for (i = n-1; i >= 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}
堆排序对{8,5,3,6,9,10,2,1,0,4,7}进行排序
排序过程展示:
第一轮:
10,9,3,6,8,5,2,1,0,4,7
第二轮:
9,8,3,6,7,5,2,1,0,4,10
第三轮:
8,7,3,6,4,5,2,1,0,9,10
第四轮:
7,4,3,6,0,5,2,1,8,9,10
第五轮:
6,4,3,1,0,5,2,7,8,9,10
第六轮:
5,4,3,1,0,2,6,7,8,9,10
第七轮:
4,2,3,1,0,5,6,7,8,9,10
第八轮:
3,2,0,1,4,5,6,7,8,9,10
第九轮:
2,1,0,3,4,5,6,7,8,9,10
第十轮:
1,0,2,3,4,5,6,7,8,9,10
第十一轮:
0,1,2,3,4,5,6,7,8,9,10
- 优点:效率高,不占用额外空间。
- 缺点:不稳定。
- 时间复杂度:最好情况O(nlogn),最坏情况O(nlogn),平均情况O(nlogn)。
- 空间复杂度:O(1)。
- 适用范围:数据规模较大的情况下,排序效率高。
- 实际应用实例:对大规模数据进行排序。
7. 希尔排序
- 将序列分为若干个子序列,对每个子序列进行插入排序,逐步缩小子序列的长度,最后对整个序列进行插入排序,实现排序。时间复杂度为O(nlogn)~O(n2),空间复杂度为O(1),适用于大数据量的排序。
void shellSort(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;
}
}
}
希尔排序对{8,5,3,6,9,10,2,1,0,4,7}进行排序
排序过程展示:
第一轮:
4,1,3,0,7,6,2,5,9,10,8
第二轮:
0,1,2,3,4,5,6,7,8,9,10
- 优点:效率高,相对于其他O(nlogn)排序算法,希尔排序在数据规模较小的情况下也可以表现出色。
- 缺点:不稳定。
- 时间复杂度:最好情况O(nlogn),最坏情况O(n2),平均情况O(n1.3)。
- 空间复杂度:O(1)。
- 适用范围:对数据规模较小的情况下也可以表现出色。
- 实际应用实例:对一段英文文本进行排序。
8. 计数排序
- 计序列中每个元素出现的次数,将统计结果进行累加,得到每个元素在有序序列中的位置,逐个将元素放到有序序列中,实现排序。时间复杂度为O(n+k),空间复杂度为O(k),适用于元素范围不大的排序。
void countingSort(int arr[], int n) {
int max = arr[0];
int i, j;
for (i = 1; i < n; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
int count[max+1];
for (i = 0; i <= max; i++) {
count[i] = 0;
}
for (i = 0; i < n; i++) {
count[arr[i]]++;
}
for (i = 1; i <= max; i++) {
count[i] += count[i-1];
}
int output[n];
for (i = n-1; i >= 0; i--) {
output[count[arr[i]]-1] = arr[i];
count[arr[i]]--;
}
for (i = 0; i < n; i++) {
arr[i] = output[i];
}
}
计数排序对{8,5,3,6,9,10,2,1,0,4,7}进行排序
排序过程展示:
0,1,2,3,4,5,6,7,8,9,10
- 优点:效率高,稳定。
- 缺点:只适用于非负整数排序。
- 时间复杂度:最好情况O(n+k),最坏情况O(n+k),平均情况O(n+k)。
- 空间复杂度:O(k)。
- 适用范围:数据规模较小,且数据集合中最大数值较小的情况下。
- 实际应用实例:对一段英文文本中字符出现频率进行排序。
9. 桶排序
- 将序列中的元素分配到若干个桶中,对每个桶中的元素进行排序,最后依次取出每个桶中的元素,实现排序。时间复杂度为O(n+k),空间复杂度为O(n+k),适用于元素范围分布比较均匀的排序。
void bucketSort(float arr[], int n) {
vector<float> b[n];
int i, j;
for (i = 0; i < n; i++) {
int bi = n * arr[i];
b[bi].push_back(arr[i]);
}
for (i = 0; i < n; i++) {
sort(b[i].begin(), b[i].end());
}
int index = 0;
for (i = 0; i < n; i++) {
for (j = 0; j < b[i].size(); j++) {
arr[index++] = b[i][j];
}
}
}
桶排序对{8,5,3,6,9,10,2,1,0,4,7}进行排序
排序过程展示:
0,1,2,3,4,5,6,7,8,9,10
- 优点:效率高,稳定。
- 缺点:需要占用额外的空间。
- 时间复杂度:最好情况O(n+k),最坏情况O(n2),平均情况O(n)。
- 空间复杂度:O(n+k)。
- 适用范围:数据规模较大,数据集合中数值分布较均匀的情况下。
- 实际应用实例:对大规模数据进行排序。
10. 基数排序
- 将序列中的元素按照位数进行排序,从低位到高位依次排序,最终得到有序序列。时间复杂度为O(d(n+k)),空间复杂度为O(n+k),适用于元素位数较小的排序。
int getMax(int arr[], int n) {
int max = arr[0];
int i;
for (i = 1; i < n; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
void countSort(int arr[], int n, int exp) {
int output[n];
int i, count[10] = {0};
for (i = 0; i < n; i++) {
count[(arr[i]/exp)%10]++;
}
for (i = 1; i < 10; i++) {
count[i] += count[i-1];
}
for (i = n-1; i >= 0; i--) {
output[count[(arr[i]/exp)%10]-1] = arr[i];
count[(arr[i]/exp)%10]--;
}
for (i = 0; i < n; i++) {
arr[i] = output[i];
}
}
void radixSort(int arr[], int n) {
int m = getMax(arr, n);
int exp;
for (exp = 1; m/exp > 0; exp *= 10) {
countSort(arr, n, exp);
}
}
基数排序对{8,5,3,6,9,10,2,1,0,4,7}进行排序
排序过程展示:
0,1,2,3,4,5,6,7,8,9,10
- 优点:效率高,稳定。
- 缺点:只适用于非负整数排序,不适合数据范围很大的情况。
- 时间复杂度:最好情况O(d(n+k)),最坏情况O(d(n+k)),平均情况O(d(n+k))。
- 空间复杂度:O(n+k)。
- 适用范围:数据规模较大,数据集合中数值位数较少的情况下。
- 实际应用实例:对学生按照学号进行排序。
🔥🔥🔥专栏推荐:C语言基础语法🔥🔥🔥