算法导论学习笔记(一)

     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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值