zoukankan      html  css  js  c++  java
  • 算法打基础——算法基本分析

    因为基础实在太差,决定从看算法导论视频+书开始重新打打基础,希望能坚持下来!!

    第一节 算法基本分析

    个人认为 本节的主要知识点有:

    1 插入排序及其分析     2 算法复杂度基本符号  3 merge sort及其分析

    1 插入排序及其分析

    插入排序伪代码:

    INSERTION-SORT (A, n) ⊳A[1 . . n]

        for j ←2 to n

            do key ←A[ j]

                 i ←j –1

                 while i > 0 and A[i] > key

                        doA[i+1] ←A[i]

                            i ←i –1

                    A[i+1] = key

    排序算法的关键就是那个key,过程是,从第二个开始往后,将key元素插到前面的元素中去(注意:前面的元素永远都是排序过的元素),

    找到比这个key小的停下来就ok了

    2 算法复杂度基本符号

    我们先介绍复杂度基本符号,然后再分析插入排序。 算法基本符号: big O ;big omega; big theta 

    f = O(g) 是说存在一个N,当n>N的时候有 f(n) < c * g(n),说明增长趋势不会超过g(n)的趋势              上界!
    f = Ω(g) 是说存在一个N,当n>N的时候有 f(n) > c * g(n),说明增长趋势至少会有g(n)的趋势              下界!
    f = Θ(g) 是说存在一个N,当n>N的时候有 c1 * g(n) < f(n) < c2 * g(n),说明增长趋势和g(n)一样       准确界!

    然后我们来分析插入排序的复杂度:

    插入排序的最差情况是当序列是逆序的时候,每个元素都要和前面所有的元素交换位置,

    复杂度: 

    平均情况是当前序列期望的交换次数是前面元素的一半的时候,

    复杂度: 

    3. merge sort 及其相关分析

     merge sort的主要思想是分治法,将一个序列分到只有一个元素,然后再按一定规则合并,自然就排序了。其主要过程就是两个:分! 合!

    伪代码如下:

    MERGE-SORT A[1 . . n]

    1.      If n= 1, done.

    2.      Recursively sort A[ 1 . . low(n/2)]

              and A[ up(n/2)+1 . . n ] .

    3.     “Merge” the 2 sorted lists.

    然后是非常重要的merge过程:

    merge 过程的伪代码非常的复杂,但是其叙述过程很简单,就是两个(已!排!序!)的序列,合并时去每个的头部,谁小就将其插

    到结果序列中,删去改头部,重复这个过程,知道所有元素处理完毕!(merge sort实现还是蛮难的,值得一试)

    merge sort 有趣的一点就是其复杂度分析(涉及到递归树)

    2T(n/2)严格来说 应该是 T(up(n/2))+T(down(n/2))

    则 归并排序的复杂度为

    这个复杂度是用递推公式来表达的,当然可以用数学方法来求,但是这里我们可以用递归树来求!

    Solve T(n) = 2T(n/2) + cn, where c > 0 is constant.

    归并排序的复杂度是nlogn 而插入排序的复杂度是n^2, 但是插入排序处理小规模数据的时候速度还是很快的。据说当数据<30时

    插入快于归并(原因?应该可以推的)

    最后附上写的插入 和 归并排序的代码:

     1 /////////////////////////CLRS   video lec1  选择排序///////////////////////////////////////////////////
     2 //
     3 //  已插入排序为主,还涉及到产生随机某个范围的数(时间种子);
     4 
     5 #include<iostream>
     6 #include<cstdlib>
     7 #include<ctime>
     8 #define random(x)(rand()%x)
     9 
    10 using namespace std;
    11 
    12 int main()
    13 {
    14     int a[100];
    15     clock_t start,finish;
    16     double funtime;
    17     srand((int)time(0));
    18     for(int i=0;i<100;i++)
    19         a[i] = random(200);    
    20     int key,j;
    21     start = clock();
    22     for(int i=1;i<100;i++)
    23     {
    24         key = a[i];
    25         j=i-1;
    26         while(j>=0&&a[j]>key)
    27         {
    28             a[j+1] = a[j];
    29             j--;
    30         }
    31         a[j+1] = key;
    32     }
    33     finish = clock();
    34     for(int i=0;i<100;i++)
    35     {
    36         cout<<a[i]<<" ";
    37     }
    38     cout<<endl;
    39     funtime=(double)(finish-start);
    40     cout<<funtime<<endl;
    41     return 0;
    42 }
    43 
    44     
    View Code
     1 /////////////////////////CLRS   video lec1  归并排序///////////////////////////////////////////////////
     2 //
     3 
     4 
     5 #include<iostream>
     6 #include<cstdlib>
     7 #include<ctime>
     8 using namespace std;
     9 
    10 #define random(x)(rand()%x)
    11 #define INF 0x3f3f3f3f
    12 
    13 void merge(int* arr, int begin, int end)
    14 {
    15     int middle;
    16     middle = (end+begin)/2;
    17     int numl = middle - begin +1;
    18     int numr =end -( middle+1)  +1;
    19     int* arrl = new int[numl+1];
    20     int* arrr = new int[numr+1];
    21     for(int i=0;i<numl;i++)
    22     {
    23         arrl[i] = arr[begin+i];
    24     }
    25     arrl[numl] = INF;
    26     for(int i=0;i<numr;i++)
    27     {
    28         arrr[i] = arr[middle+1+i];
    29     }
    30     arrr[numr] = INF;
    31     int recl = 0; int recr = 0;
    32     for(int i=0;i<(end-begin+1);i++)
    33     {
    34         if(arrl[recl]<arrr[recr])
    35         {
    36             arr[begin+i] = arrl[recl++];
    37         }
    38         else{
    39             arr[begin+i] = arrr[recr++];
    40         }
    41     }
    42 }
    43 
    44 
    45 
    46 
    47 void merge_sort(int* arr, int begin, int end)
    48 {
    49     int middle;
    50     if(begin<end)
    51     {
    52         middle = (end + begin)/2;           // 计算分割后的下标!
    53         merge_sort(arr,begin,middle);
    54         merge_sort(arr,middle+1,end);
    55         merge(arr,begin,end);
    56     }
    57 }
    58 
    59 
    60 int main()
    61 {
    62     srand(time(0));
    63     int i,j,k;
    64     int a[100];
    65     cout<<"origin array: ";
    66     for(i=0;i<100;i++)
    67     {
    68         a[i]=random(500);        
    69         cout<<a[i]<<" ";
    70     }
    71     cout<<endl;
    72 
    73     merge_sort(a,0,100-1);
    74     for(i=0;i<100;i++)
    75         cout<<a[i]<<" ";
    76     return 0;
    77 
    78 }
    79     
    Merge_sort
  • 相关阅读:
    高放的c++学习笔记之函数基础
    高放的c++学习笔记之关联容器
    高放的c++学习笔记之lambda表达式
    二分图小结
    送给大一学弟学妹的几句话
    网络流小结
    后缀数组小结
    hdu5353
    UVALive 5792 Diccionário Portuñol
    概率dp小结
  • 原文地址:https://www.cnblogs.com/soyscut/p/3370549.html
Copyright © 2011-2022 走看看