一、总述
本文是基于我对数据结构与算法的学习后,针对书中提及到的各类排序算法进行汇总,并通过C语言以代码的形式来对排序算法进行总结。
二、排序算法
(一)什么是排序算法
排序算法是一种用于将一组数据按照特定顺序进行排列的算法。排序算法通常根据元素之间的大小关系来确定它们在最终排序结果中的位置。
常见的排序算法包括:
(二)、C语言实现的排序算法
1、交换排序
冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地比较相邻两个元素的大小,并根据需要交换它们的位置,直到整个数组有序为止。冒泡排序的思想类似于水泡在水中上浮的过程,较大的元素会逐渐向右(或向左)移动到正确的位置。
(1)普通冒泡排序(交换排序)1
/*------------------------------
编辑作者:小小扫地僧
编辑日期:2023年4月24日
函数功能:冒泡排序法
--------------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define N 10 //宏定义排序的数目
/*------------------------------
函数功能:主函数
--------------------------------*/
int main()
{
int i;
int j;
int a[N];
int t;
printf("请输入%d个数字作为排序前的数字:",N);
for (i = 0; i < N; i++)
{
scanf("%d", &a[i]);
}
printf("n");
for (i = 0; i < (N - 1); i ++) //共需要9轮比较
{
for (j = 0; j < (9 - i); j ++) //第i轮共需要9-i次比较
{
if (a[j] > a[j + 1]) //如果前一个数比后一个数大,则对调两个元素
{
t = a[j];
a[j] = a[j + 1]; //数组元素交换
a[j + 1] = t;
}
}
}
printf("n排序后的数组为:");
for (i = 0; i < N; i ++)
{
printf("%d", a[i]);
}
printf("n");
system("pause");
return 0;
}
(2)常用冒泡排序
/*----------------------------
编辑作者:小小扫地僧
编辑日期:2023年4月25日
函数功能:冒泡排序的改进1
改进思路:在有些情况下,算法执行若干次后,可能已经是有序序列了,
但是上面的冒泡算法已经执行后面的比较,知道执行完n-1趟排序,这样
显然不是最佳的方式。这时候我们可以设置一个标记,用来判断一趟排序
过后有没有发生交换,如果没有发生交换,则说明数组已经有序了,已经
不需要再进行余下的比较
------------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*-----------------------------
函数功能:冒泡排序的改进
参数:两个入口参数,*N表示待排序的数组,n表示数组的大小
-------------------------------*/
void sort(int* N, int n)
{
int i;
int j;
int k;
int l;
for (i = n - 1; i > 0; i --) //外循环控制趟数,一共需要n-1趟
{
l = 0; //l初始化为0,用于记录每一趟排序的交换次数,
//如果一趟排序过后交换次数依然是0,则表示数组已经是有序的了
for (j = 0; j < i; j ++) //内循环控制每一趟比较的次数
{
if (N[j] > N[j + 1]) //相邻两个数进行比较,如果前一个数较大则进行交换
{
l ++; //如果发生了交换,l自增
k = N[j];
N[j] = N[j + 1];
N[j + 1] = k;
}
}
if (l != 0)
{
printf("第%d趟排序,发生了%d次交换n", n - i, l);
}
else
{
printf("第%d趟排序,没有发生交换,数组已经有序n", n - i);
break;
}
}
}
/*-------------------------------
函数功能:主函数
--------------------------------*/
int main(int argc, char **argv)
{
int N[6] = { 1,2,3,4,5,6 };
int n = 6;
int i;
sort(N, n);
for (i = 0; i < n; i ++)
{
printf("%d", N[i]);
if (i != n - 1)
printf(",");
}
system("pause");
return 0;
}
(3)冒泡排序优化版本
/*-------------------------
编辑作者:小小扫地僧
编辑日期:2023年4月25日
函数功能:冒泡排序的优化算法
---------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define W 10
/*-------------------------
*函数功能:对数组中的数据使用优化后的冒泡排序算法排序
*优化思想:在某些情况下,如果进行了若干次排序之后,后
面的若干个数已经是有序的,那么下一趟排序就只需要比较
前面无序的那一段就可以了。所以我们可以设置一个标记用
来记录每趟排序最后一个发生交换的位置,下一趟排序值比
较到此位置即可。
---------------------------*/
void sort(int* N, int n)
{
int i;
int j;
int k;
int flag;
flag = n - 1; // 初始化标记为-1
while (flag > 0)
{
i = flag;
flag = 0;
for (j = 0; j < i; j++)
{
if (N[j] > N[j + 1])
{
k = N[j];
N[j] = N[j + 1];
N[j + 1] = k;
flag = j;
}
}
printf("最后一次发生交换的位置为%dn", flag);
}
}
/*--------------------------
函数功能:主函数
----------------------------*/
int main(int argc, char **argv)
{
int N[W];
int n;
int i;
printf("请输入%d个待排的数据:",W);
for (n = 0; n < W; n++)
{
scanf("%d",&N[n]);
}
sort(N, W);
for (i = 0; i < W; i ++)
{
printf("%d", N[i]);
if (i != W - 1) printf(",");
}
system("pause");
return 0;
}
(4)快速排序法
快速排序(Quick Sort)是一种高效的排序算法,它采用了分治的策略。快速排序的基本思想是选择一个基准元素,将数组划分为左右两部分,使得左边的元素都比基准元素小,右边的元素都比基准元素大,然后递归地对左右两部分进行快速排序。
快速排序的时间复杂度为平均情况下 O(nlogn),最坏情况下(当每次选取的基准元素都是当前数组的最大或最小值)为 O(n^2)。虽然快速排序的最坏情况下时间复杂度较高,但由于其在平均情况下具有较好的性能,且实现简单,常被用作默认的排序算法。
/*---------------------------
编辑作者:小小扫地僧
编辑日期:2023年4月25日
函数功能:快速排序法
-----------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define SIZE 6
//快速排序
void quick_sort(int num[], int low, int high)
{
int i, j, temp;
int tmp;
i = low;
j = high;
tmp = num[low]; //任命为中间分界线,左边比他小,右边比他大,通常第一个元素是基准数
if (i > j) //如果下标i大于下标j,函数结束运行
{
return;
}
while (i != j)
{
while (num[j] >= tmp && j > i)
{
j--;
}
while (num[i] <= tmp && j > i)
{
i++;
}
if (j > i)
{
temp = num[j];
num[j] = num[i];
num[i] = temp;
}
}
num[low] = num[i];
num[i] = tmp;
quick_sort(num, low, i - 1);
quick_sort(num, i + 1, high);
}
int main(int argc, char **argv)
{
//创建一个数组
int num[SIZE] = { 0 };
int i;
//输入数字
for (i = 0; i < SIZE; i++)
{
scanf("%d", &num[i]);
}
quick_sort(num, 0, SIZE - 1);
for (i = 0; i < SIZE; i++)
{
printf(" %d ", num[i]);
}
return 0;
}
(5)选择排序
选择排序(Selection Sort)是一种简单直观的排序算法。它通过不断地选择未排序部分中的最小(或最大)元素,将其与未排序部分的第一个元素交换位置,从而逐步构建有序数组。
选择排序的特点是每次找到最小(或最大)元素需要遍历剩余未排序部分,因此它的时间复杂度始终为 O(n^2),其中 n 是待排序数组的长度。
尽管选择排序的时间复杂度较高,但由于其简单易实现的特点,在某些特定情况下可以是一个合理的选择。然而,在大规模数据集上,更高效的排序算法通常更加适用。
/*-----------------------------
编辑作者:小小扫地僧
编辑日期:2023年4月25日
函数功能:选择排序法的应用
-------------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define N 10
/*-----------------------------
函数功能:输出数组
参数:两个参数,其中n表示数组的大小
-------------------------------*/
void arr_out(int a[],int n)
{
int i = 0;
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("n");
}
/*---------------------------
函数功能:选择排序
-----------------------------*/
void arr_sort(int *p, int n)
{
int i, j;
int min = 0;
for (i = 0; i < n - 1; i++) //排序次数
{
min = i;
for (j = i + 1; j < n; j++)
{
if (p[j] < p[min])
{
min = j; //记录交换的元素下标值
}
}
if (i != min)
{
int temp = p[i];
p[i] = p[min];
p[min] = temp;
}
}
}
/*---------------------------
函数功能:主函数
-----------------------------*/
int main()
{
int a[N] = { 0 };
int i = 0;
printf("请输入%d个待排数据:", N);
for (i = 0; i < N; i++)
{
scanf("%d", &a[i]);
}
arr_sort(a, N); //排序函数
arr_out(a,N); //输出函数
system("pause");
return 0;
}
2、插入排序
(1)、直接插入排序
直接插入排序(Insertion Sort)是一种简单的排序算法。它的基本思想是将待排序的元素逐个插入到已排序序列的合适位置,从而逐步构建有序序列。
具体步骤如下:
从未排序部分依次取出一个元素,在已排序部分中找到合适的位置插入该元素。
比较当前要插入的元素与已排序部分的元素,如果当前元素小于某个已排序元素,则将该已排序元素后移一位,继续比较下一个已排序元素。
当找到插入位置时,将当前元素插入到该位置。
重复步骤2到步骤4,直到未排序部分的所有元素都被插入到已排序部分。
直接插入排序的时间复杂度为 O(n^2),其中 n 是待排序数组的长度。在数组基本有序或规模较小的情况下,直接插入排序有较好的性能。并且该算法是稳定的,即相等元素的相对顺序在排序前后保持不变。
/*------------------------
函数功能:插入排序
编辑日期:2023年4月23日
编辑人 :小小扫地僧
--------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#define N 10
/*------------------------
函数功能:打印出数组内的元素
参数 :n表示数组的大小
--------------------------*/
void print(int data[], int n)
{
int i;
for (i = 0; i < n; i ++)
{
printf("%dn", data[i]);
}
printf("n");
}
/*--------------------------
函数功能 :对数组进行插入排序
参数 :n表示数组的大小
----------------------------*/
void insertSort(int data[], int n)
{
int i = 0;
for (i = 0; i < n - 1; i ++) //for循环遍历数组元素
{
int end = i; //使用临时变量end来决定每一步排序开始的位置
int tmp = data[end + 1]; //使用临时变量tmp来存放end的下一个元素的值
while (end >= 0) //如果end小于0,则end已经超出数组的范围,即会跳出循环
{
if (tmp < data[end]) //如果tmp的值小于end,则end向后移动一位(将 < 改为 > 可以变为降序)
{
data[end + 1] = data[end];
end --; //end往前移,使得前一个元素标记位新的end
}
else //如果tmp的值大于end,则跳出while循环
{
break;
}
}
data[end + 1] = tmp; //将tmp插入到end的后一位
}
}
/*-----------------------------
函数功能 :主函数
-------------------------------*/
int main()
{
int i;
int data[N];
printf("请输入%d个要排序的数据:", N); //提示输入数据
for (i = 0; i < N; i ++)
{
scanf("%d", &data[i]);
}
insertSort(data, N);
print(data, N);
system("pause"); //使运行框停留
return 0;
}
/*-------------------------
编辑作者:小小扫地僧
编辑日期:2023年4月24日
函数功能:插入排序并显示排序过程
---------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h> //for system("pause")
#define N 8
/*--------------------------
函数功能:将指定大小的数组打印出来
参数 :n表示数组的大小
----------------------------*/
void print(int data[], int n)
{
int i;
for (i = 0; i < n; i ++)
{
printf("%d", data[i]);
}
printf("n");
}
/*----------------------------
函数功能:将指定的数组进行插入排序
参数 :n表示待排数组的大小
------------------------------*/
void insertSort(int data[], int n)
{
int i, j;
int t;
for (i = 1; i < n; i ++)
{
t = data[i];
j = i - 1;
while (j >= 0 && data[j] > t)
{
data[j + 1] = data[j];
j --;
}
data[j + 1] = t;
print(data, n); //显示排序的过程
}
}
/*-----------------------------
函数功能:主函数
-------------------------------*/
int main()
{
int data[N];
int i;
printf("please input %d number :", N);
for (i = 0; i < N; i ++)
{
scanf("%d",&data[i]);
}
printf("排序后的数组为:n");
insertSort(data, N);
system("pause"); //使运行框停留
return 0;
}
(2)折半插入排序
折半插入排序(Binary Insertion Sort)是对直接插入排序的一种改进。它通过利用二分查找的思想来确定插入位置,减少了比较的次数,从而提高了插入排序的效率。
具体步骤如下:
比较当前要插入的元素与已排序部分的中间元素,如果当前元素小于mid所指的元素,则将high指针移到mid位置之前;否则将low指针移到mid位置之后。
将当前元素插入到插入位置,并将插入位置之后的元素都后移一位。
重复步骤2到步骤6,直到未排序部分的所有元素都被插入到已排序部分。
折半插入排序的时间复杂度仍然是 O(n^2),但相比直接插入排序,它减少了比较的次数,因此在某些情况下可以稍微提高性能。然而,对于大规模乱序的数组,折半插入排序的效率仍然较低,所以在实际应用中,通常会选择更高效的排序算法。
/*--------------------------
编辑作者:小小扫地僧
编辑日期:2023年4月24日
函数功能:对数据实现折半插入排序
----------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define size 10
/*--------------------------
函数功能:折半插入排序
参数 :*num是待排序的数组(指针形式),len是数组长度
----------------------------*/
void BInsertSort(int *num, int len)
{
int i;
int j;
int low;
int mid;
int key;
for (i = 1; i < len; i ++)
{
if (num[i - 1] > num[i]) // 判断当前数据是否需要进行插入
{
key = num[i]; // 获取需要插入的数据
low = 0; // 初始查找范围为 [0, i-1](有序)
high = i - 1;
while (low <= high) // 进行折半二分算法查找插入的位置
{
mid = (low + high) / 2; // 获取中间下标
if (key <= num[mid])
{
high = mid - 1; // 如果key小于中间值,则缩小查找范围到左子序列
}
else
{
low = mid + 1; // 如果key大于中间值,则缩小查找范围到右子序列
}
}
for (j = i - 1; j >= high + 1; j--) // 整体后移
{
num[j + 1] = num[j];
}
num[high + 1] = key; // 插入数据
}
}
}
/*-----------------------------
函数功能:主函数
-------------------------------*/
int main()
{
int i;
int num[size];
printf("请输入%d个待排数据:",size);
for (i = 0; i < size; i++) //输入待排数据,存入数组中
{
scanf("%d",&num[i]);
}
printf("n");
printf("排序后的数据为:n");
BInsertSort(num, size);
for (i = 0; i < size; i++)
{
printf("%d ", num[i]);
}
printf("n");
system("pause");
return 0;
}
3、希尔排序
希尔排序(Shell Sort)是一种基于插入排序的改进算法,也被称为缩小增量排序。它通过将数组划分为多个较小的子数组,并对这些子数组进行插入排序,逐步缩小子数组的规模,最终完成整个数组的排序。
希尔排序的基本思想是,首先选择一个递减的增量序列(通常是使用 Knuth 序列),根据这个增量序列将数组分成多个子数组。然后对每个子数组进行插入排序,使得每个子数组变得部分有序。随后逐步缩小增量,再次对子数组进行插入排序。最后当增量为1时,进行最后一次插入排序,完成整个数组的排序。
具体步骤如下:
选择一个递减的增量序列,通常是使用 Knuth 序列(3h + 1,其中 h 是指数)。这样可以保证增量序列的最后一个值为1。
对每个子数组进行插入排序,使得每个子数组变得部分有序。
缩小增量,重复步骤2和步骤3,直到增量为1。
希尔排序的时间复杂度与增量序列的选择有关。在最坏情况下,其时间复杂度为 O(n^2),但在平均情况下可以达到 O(nlogn) 的性能。希尔排序的优势是相对于直接插入排序,它可以通过提前部分排序而减少后续的移动操作,从而使排序效率得到提高。
/*-----------------------------
编辑作者:小小扫地僧
编辑日期:2023年4月24日
函数功能:希尔排序
-------------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define N 8
/*-----------------------------
函数功能:打印数组
-------------------------------*/
void arr_out(int a[],int n)
{
int i = 0;
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("n");
}
/*-------------------------------
函数功能:利用希尔排序算法对数据进行排序
---------------------------------*/
void arr_sort(int *p, int n)
{
int step = 0; //步长
int temp = 0; //用来保存第二段数据
int i;
int j;
for (step = n / 2; step > 0; step /= 2)
{
for (i = step; i < n; i ++)
{
temp = p[i];
for (j = i - step; j >= 0 && p[j] > temp; j -= step)
{
p[j + step] = p[j]; //当满足条件时第一次j+step = i;
//后面的j+step = 上一次j的值
}
p[j + step] = temp;
}
}
}
/*------------------------------
函数功能:主函数
--------------------------------*/
int main()
{
int a[N] = { 0 };
int i = 0;
printf("请输入%d个待排数据:",N);
for (i = 0; i < N; i ++)
{
scanf("%d", &a[i]);
}
arr_sort(a, N); //排序函数
arr_out(a,N); //输出函数
system("pause");
return 0;
}
4、堆排序
堆排序(Heap Sort)是一种基于二叉堆数据结构的排序算法。它利用堆的性质进行排序,通过将数组构建成一个最大堆(或最小堆),然后逐步取出堆顶元素并调整堆来实现排序。
具体步骤如下:
构建最大堆(或最小堆):将待排序的数组看作完全二叉树,并从最后一个非叶子节点开始,依次向上调整每个子树,使其满足堆的性质。这样就得到一个最大堆,即每个父节点的值都大于等于其子节点(或最小堆,每个父节点的值都小于等于其子节点)。
重复步骤2和步骤3,直到堆为空或只剩一个元素。
最终得到的数组就是有序的。
堆排序的时间复杂度是 O(nlogn),其中 n 是待排序数组的长度。堆排序在实践中具有较好的性能,尤其适用于对大规模数据进行排序,但相比其他排序算法,其实现较为复杂。此外,堆排序是一种不稳定的排序算法,即相等元素的相对顺序可能会发生改变。
/*---------------------------
编辑作者:小小扫地僧
编辑日期:2023年4月25日
函数作用:堆排序算法
-----------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*--------------------------
函数功能:打印出数组
----------------------------*/
void Print(int* arr, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
}
/*----------------------------
函数功能:交换两个数据的地址
------------------------------*/
void Swap(int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
/*------------------------------
函数功能:向下调整算法
--------------------------------*/
void AdjustDown(int* arr, int n, int root)
{
int parent = root;
int child = parent * 2 + 1; //默认先对左孩子进行操作
while (child < n)
{
//选出左右孩子较小的那一个
//防止没有右孩子,数组越界
if (child + 1<n && arr[child + 1] > arr[child]) //建小堆用小于,建大堆用大于
{
child += 1;
}
if (arr[child] > arr[parent]) //建小堆用小于,建大堆用大于
{
Swap(&arr[child], &arr[parent]); //交换父子的值
parent = child; //父亲到孩子的位置,继续向下调整
child = parent * 2 + 1; //默认又从左孩子开始
}
else
{
break;
}
}
}
void HeapSort(int* arr, int n)
{
for (int i = (n - 1 - 1) / 2; i >= 0; i --) //建堆,排升序建大堆,排降序建小堆
{
AdjustDown(arr, n, i);
}
//排升序
int end = n - 1; //end为最后一个数的下标
while (end > 0) //剩余超过一个数就交换
{
Swap(&arr[0], &arr[end]);
AdjustDown(arr, end, 0);
end--;
}
}
/*---------------------------
函数功能:测试函数
-----------------------------*/
void test()
{
int arr[] = { 10,9,8,7,6,5,3,5,4,2,0,1 };
int n = sizeof(arr) / sizeof(arr[0]);
HeapSort(arr, n);
Print(arr, n);
}
/*----------------------------
函数功能:主函数
------------------------------*/
int main()
{
test();
system("pause");
return 0;
}
5、归并排序
归并排序(Merge Sort)是一种基于分治思想的排序算法。它将待排序的数组不断地划分为较小的子数组,然后对这些子数组进行递归地排序,最后将排好序的子数组合并成一个有序数组。
具体步骤如下:
归并排序的关键在于合并操作,它要求合并的两个子数组都是有序的。通过递归地将数组划分为较小的子数组再进行合并,可以保证最终整个数组是有序的。
归并排序的时间复杂度始终为 O(nlogn),其中 n 是待排序数组的长度。由于归并排序需要额外的空间来存储临时数组,在空间复杂度上需要额外的 O(n) 空间。归并排序是稳定的排序算法,即相等元素的相对顺序在排序前后保持不变。
/*---------------------------
编辑作者:小小扫地僧
编辑日期:2023年4月25日
函数功能:归并排序
-----------------------------*/
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
/*------------------------------
归并排序:将一个数组中两个相邻有序空间合并成一个
参数说明:
a -- 包含两个有序区间的数组
start -- 第一个有序区间的起始地址
mid -- 第一个有序区间的结束地址。也是第二个有序区间的起始地址
end -- 第二个有序区间的结束地址
-------------------------------*/
void merge(int a[], int start, int mid, int end)
{
int* tmp = (int*)malloc((end - start + 1) * sizeof(int)); // tmp是汇总2个有序区间的临时区域。
int i = start; // 第一个有序区的索引
int j = mid + 1; // 第二个有序区的索引
int k = 0; // 临时区域的索引
while (i <= mid && j <= end)
{
if (a[i] <= a[j])
{
tmp[k ++] = a[i ++];
}
else
{
tmp[k ++] = a[j ++];
}
}
while (i <= mid)
{
tmp[k ++] = a[i ++];
}
while (j <= end)
{
tmp[k ++] = a[j ++]; // 将两个有序区间合并
}
for (i = 0; i < k; i ++)
{
a[start + i] = tmp[i]; // 排序后的元素,全部都整合到数组a中
}
free(tmp);
tmp = NULL;
}
// 归并排序--从上往下
// 参数说明:
// a -- 待排序数组
// start -- 数组的起始地址
// end -- 数组的结束地址
//
void merge_sort_up_to_down(int a[], int start, int end)
{
if (a == NULL || start >= end)
{
return;
}
int mid = (end + start) / 2;
merge_sort_up_to_down(a, start, mid); // 递归排序a[start..mid]
merge_sort_up_to_down(a, mid + 1, end); // 递归排序a[mid..end]
// a[start..mid]和a[mid..end]是两个有序空间
// 将它们排序成一个有序空间a[start..end]
merge(a, start, mid, end);
}
int main()
{
int arr[] = { 9,5,1,6,2,3,0,4,8,7 };
merge_sort_up_to_down(arr, 0, 9);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
printf("n");
system("pause");
return 0;
}
6、基数排序
举个简单的例子如下L:
先按照个位排序:
再按照十位排序:
再按照百位排序:
#include <stdio.h>
// 获取数组中的最大值
int getMax(int arr[], int n) {
int max = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
// 基数排序函数
void radixSort(int arr[], int n) {
int max = getMax(arr, n); // 获取数组中的最大值
// 根据位数进行排序
for (int exp = 1; max / exp > 0; exp *= 10) {
int output[n]; // 存储排序后的结果数组
int count[10] = {0}; // 存储每个数字出现的次数(0-9)
// 计算每个数字出现的次数
for (int i = 0; i < n; i++) {
count[(arr[i] / exp) % 10]++;
}
// 计算累加次数
for (int i = 1; i < 10; i++) {
count[i] += count[i - 1];
}
// 将元素按照当前位数排序到 output 数组中
for (int i = n - 1; i >= 0; i--) {
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}
// 将排序后的结果复制回原数组
for (int i = 0; i < n; i++) {
arr[i] = output[i];
}
}
}
// 打印数组元素
void printArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("n");
}
int main() {
int arr[] = {170, 45, 75, 90, 802, 24, 2, 66};
int n = sizeof(arr) / sizeof(arr[0]);
printf("原始数组:");
printArray(arr, n);
radixSort(arr, n);
printf("排序后的数组:");
printArray(arr, n);
return 0;
}
原文地址:https://blog.csdn.net/m0_73931287/article/details/134752798
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_49012.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!