算法导论 第八章答案
8.2-4 :在O(1)的时间内,回答出输入的整数中有多少个落在区间[a...b]内。给出的算法的预处理时间为O(n+k)
算法思想:利用计数排序,由于在计数排序中有一个存储数值个数的临时存储区C[0...k],利用这个数组即可。
#include
using namespace std;
//通过改编计数排序而来,因为有些部分需要注释掉
void counting_sort(int*&a, int length, int k, int*&b, int*&c);
int main()
{ const int LEN =100;
int*a =newint[LEN];
for(int i =0; i < LEN; i++)
a[i] = (i -50)*(i -50) +4;
int* b =new int[LEN];
const int k =2504;
int* c =new int[k +1];
counting_sort(a, LEN, k, b, c);
//这里需要注释掉
//for(int i = 0; i < LEN; i++)
//cout<
int m; int n;
while(cin>>m>>n)
{ if(m >n)
cout<<"区间输入不对"< else { if(n <0) cout<<"个数为"<<0< else if(m <=0&& n <= k) cout<<"个数为"< else if(n > k && m >0) cout<<"个数为"< else if(n > k && m <=0) cout<<"个数为"< else cout<<"个数为"< }} return 0; } void counting_sort(int*&a, int length, int k, int*&b, int*&c) { for(int i =0; i < k +1; i++) c[i] =0; for(int i =0; i < length; i++) c[a[i]]++; for(int i =1; i < k +1; i++) c[i] = c[i] + c[i-1]; //这里需注释,因为对c数组内的元素进行减减操作会使其改变 /*for(int i = length - 1; i >= 0; i--) { b[c[a[i]] - 1] = a[i]; c[a[i]]--; }*/ } PS:计数排序的总时间为O(k+n),在实践中,如果当k = O(n)时,我们常常采用计数排序, 这时其运行时间为O(n) 8.3-4 :说明如何在O(n)时间内,对0到n^2 - 1之间的n个整数进行排序。 算法思想:1.把这n个数看成n进制数,那么每个数只有两位,因而循环只需两次 2.调用通用的基数排序(在这写着,留着以后用) 在此题中我选择n = 15,即数组中有15个数,依次为0, 3, 8, ..., 224,但是将顺序打乱 采用的是基数排序,在实践中,其排序时间为O(d*(n+k)),但很耗内存,有时甚至比快速排序更快,具体应用再看。 #include #include using namespace std; void radix_sort(int a[], const int d, const int length, int radix); int getBit(int m, int i, int radix); int pow2(int a, int b); int main() { //数组长度const int LEN =15; int a[LEN] = {35, 48, 0, 8, 15, 80, 99, 3, 24, 168, 195, 224, 63, 120, 143}; //多少位const int d =2; //基数const int radix =15; //在这调用的是通用的基数排序算法,可以任意改变基数radix, //但记得改变d,因为radix改变的话,数字的位数会改变, //最简单的是十进制改成二进制,位数激增 radix_sort(a, d, LEN, radix);