5月17日拿到从当当网上买的心仪已久的中文版的《算法导论》,很是高兴。书很厚,印刷质量也不错。就是纸质有点薄。不过瑕不掩玉。还是挺满意的。
欣喜过后,净手定神。翻开新书。
第一章——算法在计算中的作用。虽说所说的内容都是已经熟悉的东西。但是大师的作品还是显示了作者学识的渊博,引人入胜。
第二章——算法入门。本章借插入排序的例子展示了算法分析的过程。一些比较浅显的东西。然后借合并排序介绍了分治法(Divide-and-conquer)。
第二章的几个思考题比较有趣,值得好好的想一想:
1、在合并排序中对小数组采取插入排序:即把插入排序和合并排序结合起来,发挥插入排序在处理小数组时的优势。好像记得在实践中可以取15为界。
2、霍纳规则
这样表示的多项式可以在O(n)时间算出。
3、逆序数
朴素的逆序数的计算方法的复杂度为O(n^2)。由合并排序的启发可以得到O(nlgn)的计算方法。
/**/
/*
Name: 计算由<1,2....n> 生成的随机序列的逆序数
Copyright:
Author: 王瑞
Date: 19-05-08 11:00
Description: 修改合并排序得到的方法(算法导论思考题2-4), 复杂度O(nlgn)
*/
#include " iostream "
#include " ctime "
#include " vector "
using namespace std;
int my_merge(vector < int > & v, int a, int mid, int b)
... {
vector<int> tp;
int cnt = 0;
int i = a;
int j = mid+1;
while(i <= mid && j <= b)...{
if(v[i]<v[j])
tp.push_back(v[i++]);
else...{
tp.push_back(v[j++]);
cnt += (mid-i+1);
}
}
while(i <= mid)
tp.push_back(v[i++]);
while(j <= b)
tp.push_back(v[j++]);
for(int i = a;i <= b; i++)
v[i] = tp[i-a];
return cnt;
}
int cnt(vector < int > & v, int a, int b)
... {
if(a < b)...{
int mid = (a+b)/2;
int s1 = cnt(v,a,mid);
int s2 = cnt(v,mid+1,b);
int s = my_merge(v,a,mid,b);
return s1+s2+s;
}
else
return 0;
}
int main()
... {
int n;
cin >> n;
vector<int> v;
srand(time(0));
for(int i = 0; i < n; i++)...{
int t = (rand()%n) + 1;
if(find(v.begin(),v.end(),t) == v.end())
v.push_back(t);
else
i--;
}
for(int i = 0; i < n; i++)
cout << v[i] << " ";
cout << endl;
int c = cnt(v,0,v.size()-1);
cout << c << endl;
return 0;
}
Name: 计算由<1,2....n> 生成的随机序列的逆序数
Copyright:
Author: 王瑞
Date: 19-05-08 11:00
Description: 修改合并排序得到的方法(算法导论思考题2-4), 复杂度O(nlgn)
*/
#include " iostream "
#include " ctime "
#include " vector "
using namespace std;
int my_merge(vector < int > & v, int a, int mid, int b)
... {
vector<int> tp;
int cnt = 0;
int i = a;
int j = mid+1;
while(i <= mid && j <= b)...{
if(v[i]<v[j])
tp.push_back(v[i++]);
else...{
tp.push_back(v[j++]);
cnt += (mid-i+1);
}
}
while(i <= mid)
tp.push_back(v[i++]);
while(j <= b)
tp.push_back(v[j++]);
for(int i = a;i <= b; i++)
v[i] = tp[i-a];
return cnt;
}
int cnt(vector < int > & v, int a, int b)
... {
if(a < b)...{
int mid = (a+b)/2;
int s1 = cnt(v,a,mid);
int s2 = cnt(v,mid+1,b);
int s = my_merge(v,a,mid,b);
return s1+s2+s;
}
else
return 0;
}
int main()
... {
int n;
cin >> n;
vector<int> v;
srand(time(0));
for(int i = 0; i < n; i++)...{
int t = (rand()%n) + 1;
if(find(v.begin(),v.end(),t) == v.end())
v.push_back(t);
else
i--;
}
for(int i = 0; i < n; i++)
cout << v[i] << " ";
cout << endl;
int c = cnt(v,0,v.size()-1);
cout << c << endl;
return 0;
}