博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
几种线性时间排序
阅读量:6760 次
发布时间:2019-06-26

本文共 2529 字,大约阅读时间需要 8 分钟。

一般我们使用的堆排序,归并排序都是属于比较排序,也就是通过比较元素的大小来进行排序,可以通过决策树分析出比较排序的时间下界是O(nlgn),堆排序和归并排序都是渐进最优的比较排序算法。还有其他的排序方法不是通过比较,下面总结一下:

一:计数排序

大致思路是将数组中所有元素对应小于这个元素的个数存储起来,这样我们可以直接知道这个元素的位置,因为可能出现相同的元素,所以我们从后面输出而且每次找到一个元素的位置后要把对应的小于x的个数减一,这样再次输出时就被会放到前一个位置上。最后的时间很好是O(n),但是要开三个数组,而且其中一个数组要开从0到所有比较的数中最大的数,所以是典型的空间换时间,如果比较的元素中有一些非常大就没有办法进行排序。
#include
#include
using namespace std;const int maxnum = 0xffff;const int maxsize = 0xff;int length;void CounterSort(int a[], int b[], const int k){ int c[maxnum]; int i; for (i = 0; i <= k; i++) c[i] = 0; for (i = 1; i <= length; i++)//统计a中不同的数分别出现的个数 c[a[i]]++; for (i = 1; i <= k; i++) //将c[i]现在代表有几个数小于或等于i c[i] = c[i] + c[i - 1]; for (i = length; i >= 1; i--) { b[c[a[i]]] = a[i]; c[a[i]]--; //对相同元素的个数减一 }}int main(){ int a[maxsize], b[maxsize]; cin >> length; int max = -1; for (int i = 1; i <= length; i++) { cin >> a[i]; if (max < a[i]) max = a[i]; } CounterSort(a, b, max); for (int i = 1; i <= length; i++) cout << b[i] << " "; cout << endl; return 0;}

二:基数排序&&桶排序

基数排序就是用来排序一些位数相等的数时比较好,基本思路是从低位开始排序,再一位一位往前,总共排序位数d次,能够确保完全拍好序,时间复杂度是O(d(n+k))。感觉跟桶排序是一个意思,可能实现不一样吧,自己写的是感觉基数排序要靠桶排序实现,这两差不多。
#include
#include
using namespace std;const int maxsize = 0xfff;int n;void BucketSort(int a[]);int GetDigit(int num);void PushNum(int a[], int b[10][maxsize], int digit);void CollectNum(int a[], int b[10][maxsize]);int main(){ int a[maxsize]; cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i <= n; i++) cout << a[i] << " "; cout << endl; BucketSort(a); for (int i = 1; i <= n; i++) cout << a[i] << " "; cout << endl; return 0;}void BucketSort(int a[]){ int b[10][maxsize] = {0}; int max = -1; for (int i = 1; i <= n; i++) if (max < a[i]) max = a[i]; int digit = GetDigit(max); for (int i = 1; i <= digit; i++) { PushNum(a, b, i); CollectNum(a, b); if (i != digit) memset(b, 0, sizeof(b)); }}int GetDigit(int num)//求所有数中位数最高的位数{ int digit = 0; while (num) { digit++; num /= 10; } return digit;}void PushNum(int a[], int b[10][maxsize], int digit){ int div = 1; for (int i = 1; i <= digit; i++) div *= 10; for (int i = 1; i <= n; i++) { int num = (a[i] % div - a[i] % (div / 10)) / (div / 10);//得到相应的第div/10位上的数 int count = ++b[num][0];//用b[num][0]存储对应的数有几个元素 b[num][count] = a[i]; }}void CollectNum(int a[], int b[10][maxsize]){ int k = 0; for (int i = 0; i < 10; i++) for (int j = 1; j <= b[i][0]; j++) a[++k] = b[i][j];}

转载于:https://www.cnblogs.com/seasonal/p/10343711.html

你可能感兴趣的文章
Smart Device Framework 2.2 发布了
查看>>
Humble Numbers soj1029
查看>>
程序员技术练级攻略
查看>>
ls只显示文件名/只显示文件夹名
查看>>
Java并发编程:同步容器
查看>>
水晶报表之动态列--简化版实现
查看>>
验证控件的使用四( RangeValidator)
查看>>
网络编程(一):用C#下载网络文件的2种方法
查看>>
复制graphic
查看>>
基于NopCommerce的开源电商系统改造总结
查看>>
JavaScript是怎样让互联网变慢的(及对策)
查看>>
诺基亚预装WIN8系统的LUMIA平板真机曝光-应用电台
查看>>
遇见C++ PPL:C++ 的并行和异步
查看>>
软件开发中关于向后兼容的理解
查看>>
ios开发之 MPMoviePlayerController 视频播放器
查看>>
count(*)、count(val)和count(1)的解释
查看>>
[Leetcode] Largest Rectangle in Histogram
查看>>
final (Java)
查看>>
The Master of Science degree in Computer Scienc
查看>>
利用Stack倒序List,利用Set使List不能添加重复元素
查看>>