第二章 算法基础

Introduction to Algorithms

1.Insertion Sort(插入排序)
伪代码如下:
在这里插入图片描述
c++代码实现:

#include<iostream>
#include<vector>
using namespace std;
void insert_sort(vector<int>& a)
{
    for(int j=1;j<a.size();j++)
    {
        int key=a[j];
        int i=j-1;
        while(i>-1 && a[i]>key){
            a[i+1]=a[i];
            i=i-1;
        }
        a[i+1]=key;
    }
}
int main()
{
    vector<int> a;
    a.push_back(3);
    a.push_back(1);
    a.push_back(2);
    a.push_back(4);
    a.push_back(5);
    insert_sort(a);
    for(int i=0;i<a.size();i++)
    cout<<a[i]<<endl;
}

算法实现细节:
在这里插入图片描述
2.循环不变式

  • A technique for proving that an algorithm is correct.Identify a loop-invariant(循环不变式)
  • Initialization(初始化):循环的第一次迭代之前,它为真。
  • Maintenance(保持):如果循环的某次迭代之前它为真,那么下次迭代之前,它仍为真。
  • Termination(终止):在循环终止时,不变式为我们提供一个有用的性质,该性质有助于证明算法是正确的。

让我们来看看对于插入排序如何证明这些性质成立:
在这里插入图片描述
3.Analysis algorithms

  • 分析算法的结果意味着预测算法需要的资源,虽然有时我们主要关心像memory(内存)、communication bandwidth(通信带宽)、computer hardware(计算机硬件)等。
  • 但通常我们想度量的是 computational time(计算时间)

在这里插入图片描述
在这里插入图片描述
n:执行n-1次,终止时还需执行一次判断。
在这里插入图片描述
最佳情况有tj=1。
在这里插入图片描述
最坏情况有tj=j。(因为逆序,所以每次都需j次)

最坏与平均情况分析:

  • 一个算法的最坏情况运行时间给出了任何输入的运行时间的一个上界。
  • 对某些算法,最坏情况经常出现。
  • 平均情况往往与最坏情况大致一样差。

4.Order of Growth(增长量级)
只考虑公式中最重要的项,因为当n的值很大时,低阶项相对来说不太重要。
在这里插入图片描述
5.Divide-and-Conquer(分治法)
在这里插入图片描述
分治模式在每层递归时都有三个步骤:

  • 分解原问题为若干子问题。
  • 解决这些子问题,递归地求解各子问题。
  • 合并这些子问题的解成为原问题的解。

6.Merge Sort Algorithm(归并排序)
在这里插入图片描述
归并排序完全遵守分治模式:

  • 分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。
  • 解决:使用归并排序递归地排序两个子序列。
  • 合并:合并两个已排序的子序列以产生已排序的答案。
    在这里插入图片描述
    MERGE-SORT:
    在这里插入图片描述
    MERGE:
    在这里插入图片描述
    代码实现如下:
#include<iostream>
using namespace std;
void merge(int A[],int p,int q,int r){
    int n1=q-p+1;
    int n2=r-q;
    int L[n1+1],R[n2+1];
    int i,j;
    for(i=0;i<n1;i++)
    L[i]=A[p+i];
    for(j=0;j<n2;j++)
    R[j]=A[q+j+1];
    L[n1]=100000;
    R[n2]=100000;
    i=0;j=0;
    for(int k=p;k<=r;k++)
    {
        if(L[i]<=R[j])
        {
            A[k]=L[i];
            i++;
        }
        else{
            A[k]=R[j];
            j++;
        }
    }
}
void merge_sort(int A[],int p,int r)
{
    if(p<r)
    {
        int q=(p+r)/2;
        merge_sort(A,p,q);
        merge_sort(A,q+1,r);
        merge(A,p,q,r);
    }
}
int main()
{
    int a[8]={5,2,4,7,1,3,2,6};
    merge_sort(a,0,7);
    for(int i=0;i<8;i++)
    cout<<a[i]<<endl;
    system("pause");
}

原理解释如下:
在这里插入图片描述
7.分析分治算法
在这里插入图片描述
把原问题分解成a个子问题,每个子问题的规模是原问题的1/bn<=c代表问题规模足够小;D(n)代表分解问题成为子问题需要的时间;C(n)代表合并子问题的解成为原问题的解需要的时间。

归并算法的分析:
在这里插入图片描述
总代价可用递归树(Recursion Tree)进行分析:

  1. 初始化:
    在这里插入图片描述

  2. 递归代换一次:
    在这里插入图片描述

  3. 递归代换两次:
    在这里插入图片描述

  4. 最终结果:
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值