几种线性时间排序
2016-07-26 20:53
260 查看
一般我们使用的堆排序,归并排序都是属于比较排序,也就是通过比较元素的大小来进行排序,可以通过决策树分析出比较排序的时间下界是O(nlgn),堆排序和归并排序都是渐进最优的比较排序算法。还有其他的排序方法不是通过比较,下面总结一下:
一:计数排序
大致思路是将数组中所有元素对应小于这个元素的个数存储起来,这样我们可以直接知道这个元素的位置,因为可能出现相同的元素,所以我们从后面输出而且每次找到一个元素的位置后要把对应的小于x的个数减一,这样再次输出时就被会放到前一个位置上。最后的时间很好是O(n),但是要开三个数组,而且其中一个数组要开从0到所有比较的数中最大的数,所以是典型的空间换时间,如果比较的元素中有一些非常大就没有办法进行排序。#include<iostream> #include<algorithm> 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<iostream> #include<algorithm> 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]; }
相关文章推荐
- JavaScript演示排序算法
- 算法之排序算法的算法思想和使用场景总结
- PHP版本常用的排序算法汇总
- JavaScript实现多种排序算法
- php 地区分类排序算法
- js三种排序算法分享
- Javascript中的常见排序算法
- java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述
- 使用Java实现希尔排序算法的简单示例
- 排序算法的javascript实现与讲解(99js手记)
- 图文详解Heap Sort堆排序算法及JavaScript的代码实现
- C++中十种内部排序算法的比较分析
- Java实现几种常见排序算法代码
- 浅谈javascript实现八大排序
- C语言演示对归并排序算法的优化实现
- JS及PHP代码编写八大排序算法
- PHP常用的排序和查找算法
- JavaScript中九种常用排序算法
- STl中的排序算法详细解析
- 算法学习入门之使用C语言实现各大基本的排序算法