线性时间排序
来源:互联网 发布:软件平台架构 编辑:程序博客网 时间:2024/06/14 23:56
说明:比较排序算法的复杂度下界是 O(nlog(n))
一、计数排序(复杂度是O(n))
计数排序要求被排序元素都是整数型变量,即元素能用数组的指标表示
(1)统计个元素 i 的个数
(2)计算不超过 i 包括 i 的元素的个数
(3)将元素 i 放入适当的位子。
算法复杂度第一大步统计数字是n+k,其中k表示数字可能取到的最大的数
第二步需要复杂度是O(n),因此总的复杂度是 O(n+k). 当k=O(n)时,复杂度是O(n).
代码1:
#include<iostream>using namespace std;void COUNTING_SORT(int*a, int *b, int n){int c[10] = { 0 };for (int i = 0; i < n; i++)//记录c的序号(即a中数组元素)出现的次数c[a[i]] = c[a[i]] + 1;for (int i = 1; i <=n; i++)//序号所对应的值累加c[i] = c[i] + c[i - 1];for (int i = n-1; i>=0; i--)//按照序号的大小将所对应的值赋给b,计入数组下标应从0开始,因此用C[A[j]]减去1{b[c[a[i]]-1] = a[i];c[a[i]] = c[a[i]] - 1;}}void Print(int *a, int n){ for (int i = 0; i<n; i++) {cout<<a[i]<<" "; } cout << endl;}int main(){int a[9] = { 5, 4, 9, 1, 7, 6, 2, 3, 8 };int b[9] = {0};cout << "原序列:" << endl;Print(a, 9);COUNTING_SORT(a, b, 9);/*排好序的结果*/cout << "已排序列:" << endl;Print(b, 9);system("pause");return 0;}
代码2:
#include <iostream>using namespace std;//此程序是实现计数排序算法,要特别注意指标问题void COUNTING_SORT(vector<int> A, vector<int>& B, int k);void COUNTING_SORT(vector<int> A, vector<int>& B, int k){vector<int> C(k + 1, 0);//统计A中重复元素的个数,C的指标表示这个元素的值,C的值表示对应元素的个数for (int j = 0; j<A.size(); j++)C[A[j]] = C[A[j]] + 1;//统计这个值在数组中的放置的位置,即排在第几位for (int i = 1; i <= k; i++)C[i] = C[i] + C[i - 1];//一次将A中的每个元素放到正确的位置,计入数组下标应从0开始,因此用C[A[j]]减去1for (int j = A.size() - 1; j >= 0; j--){B[C[A[j]] - 1] = A[j];C[A[j]] = C[A[j]] - 1;}}void Print(vector<int>a){vector<int>::iterator iter = a.begin();for (; iter != a.end();)cout << *iter++ << " ";cout << endl;}int main(){int a[] = { 1, 4, 3, 2, 0, 4, 3, 5, 7, 5, 4, 6, 7, 8, 5, 9, 6, 4, 3, 4, 0 };int k = 9;vector<int> A(a, a + 20);vector<int> B(20, 0);cout << "原始数据:" << endl;Print(A);COUNTING_SORT(A, B, k);vector<int>::iterator i;cout << "已排序结果:" << endl;Print(B);system("pause");return 0;}
二、基数排序(是基于计数排序的算法)
对于比较大的一列整数,如329,457,736,823,67,384如果用计数排序就不能用了,因为k很大
这时可以使用基数排序,即按照位依次排,如下图所示
每一步用一次计数排序
假设数的位数是d,有n个数,则总的算法复杂度是 O(d(n+k)) 这里的k<9
复杂度关于 n 几乎是线性关系。
代码:
#include<iostream>using namespace std;void exchange(char** str, int j);void char_bubble_sort(char** str, int d, int len);void radix_sort(char** str, int d, int len);void exchange(char** str, int j){char* tmp;tmp = str[j];str[j] = str[j + 1];str[j + 1] = tmp;}//对基数排序中的每趟排序使用冒泡排序 void char_bubble_sort(char** str, int d, int len){for (int i = 0; i<len; i++)for (int j = 0; j<len - 1; j++){if (str[j][d]>str[j + 1][d]){exchange(str, j);}}}//基数排序 void radix_sort(char** str, int d, int len){for (int i = d - 1; i >= 0; i--){char_bubble_sort(str, i, len);}}void Print(char **a, int n){ for(int k=0; k<n; k++){ if(k!=15)printf("%s ",a[k]);elseprintf("%s",a[k]);} cout << endl;}int main(){char* str[16]={"COW","DOG","SEA","RUG","ROW","MOB","BOX","TAB","BAR","EAR","TAR","DIG","BIG","TEA","NOW","FOX"}; cout << "原始数据:" << endl;Print(str, 16);radix_sort(str,3,16); cout << "已排序结果:" << endl;Print(str, 16);system("pause");return 0;}
三、桶排序(期望时间复杂度O(n))
桶排序算法想法类似于散列表
首先要假设待排序的元素输入符合某种均匀分布,例如数据均匀分布在[ 0,1)区间上.
则可将此区间划分为10个小区间,称为桶,每个桶存放一个链表,对散布到同一个桶
中的元素在排序。
代码:
#include<iostream> #include<algorithm> #include<math.h> using namespace std;int a[100];int b[100];int c[100];//定义桶对象 class Bucket{public:float d;Bucket* next;Bucket(){}Bucket(float d){this->d = d;}}*bucket[11];//计数排序 void conunting_sort(int *a, int *b, int k, int len){//初始化c数组 for (int i = 1; i <= k; i++)c[k] = 0;//对a中元素出现次数的统计 for (int j = 1; j <= len; j++)c[a[j]]++;//对c进行累加,得到位置信息 for (int x = 1; x <= k; x++)c[x] += c[x - 1];//使用位置信息顺序重建数组 for (int y = len; y >= 1; y--){b[c[a[y]]] = a[y];c[a[y]]--;}for (int z = 1; z <= len; z++){a[z] = b[z];}}void exchange(char** str, int j){char* tmp;tmp = str[j];str[j] = str[j + 1];str[j + 1] = tmp;}//对基数排序中的每趟排序使用冒泡排序 void char_bubble_sort(char** str, int d, int len){for (int i = 0; i<len; i++)for (int j = 0; j<len - 1; j++){if (str[j][d]>str[j + 1][d]){exchange(str, j);}}}//基数排序 void radix_sort(char** str, int d, int len){for (int i = d - 1; i >= 0; i--){char_bubble_sort(str, i, len);}}//对桶排序的每趟使用冒泡排序 void link_bubble_sort(Bucket* buck){Bucket *t, *tn;float s;for (Bucket* p = buck; p->next != NULL; p = p->next){for (Bucket* q = buck; q->next->next != NULL; q = q->next){if (q->next->d > q->next->next->d){s = q->next->next->d;q->next->next->d = q->next->d;q->next->d = s;}}}}//桶排序 void bucket_sort(float *a, int len){//分桶 for (int i = 0; i<len; i++){Bucket *p;for (p = bucket[int(11 * a[i])]; p->next != NULL; p = p->next);p->next = new Bucket(a[i]);}//没个桶内进行排序 for (int j = 0; j<len; j++){link_bubble_sort(bucket[j]);}for (int k = 0; k<len; k++){for (Bucket *q = bucket[k]; q->next != NULL; q = q->next){printf("%.2f ", q->next->d);}}printf("\n");}int main(){/*int len; char* str[16]={"COW","DOG","SEA","RUG","ROW","MOB","BOX","TAB","BAR","EAR","TAR","DIG","BIG","TEA","NOW","FOX"}; *//* scanf("%d",&len);for(int i=1; i<=len; i++){scanf("%d",&a[i]);}conunting_sort(a,b,len,len);for(int j=1; j<=len; j++){if(j!=len)printf("%d ",a[j]);elseprintf("%d\n",a[j]);}*/float a[11] = { 0.21, 0.12, 0.39, 0.72, 0.94, 0.78, 0.17, 0.23, 0.26, 0.68, 0.11 };for (int z = 0; z<11; z++){bucket[z] = new Bucket();}bucket_sort(a, 11); /* radix_sort(str,3,16); for(int k=0; k<16; k++){if(k!=15)printf("%s ",str[k]);elseprintf("%s\n",str[k]);}*/system("pause");return 0;}
阅读全文
0 0
- 线性时间排序
- 线性时间排序
- 线性时间排序习题
- 线性时间排序
- 线性时间排序
- 线性时间的排序
- 线性时间排序
- 线性时间排序
- 线性时间排序算法
- 线性时间排序-counting_sort
- 线性时间排序
- 算法-线性时间排序
- 线性时间排序
- 线性时间排序
- 线性时间复杂度排序
- 线性时间排序
- 线性时间排序
- 线性时间选择排序
- 【知了堂学习笔记】JfreeChart制作一些简单的报表
- Whitelabel Error Page(2)之Internal Server Error
- struts2中 ServletActionContext与ActionContext区别
- Swift中懒加载
- CGlib动态代理中Enhancer.create()函数的逻辑
- 线性时间排序
- 虚拟机中linux系统启动的tomcat无法在本机访问的问题
- 缓存穿透与缓存雪崩
- 软件测试知识点
- 直方图均衡化
- Python——安装Scrapy时出现各种错误
- hdu2825-(AC自动机+状压DP)
- Java开发牛人十大必备网站
- Ubuntu问提记录