C++数据结构-1

介绍基于C++的数据结构-参考书目[数据结构、算法与应用(C++语言描述)--赵宏(主编)]

【基本概念准备】
**信息:**对现实世界中事物的存在方式或运动状态的反映,在计算机中以数据的形式存储。
**数据:**数据结构中的数据是指所有能输入计算机并被计算机识别、存储和加工处理的符号,是计算机处理的信息的符号化表示形式。
**数据元素:**是数据的基本单位,也是数据结构中讨论的基本单位,简称元素。
**数据项:**数据项是数据不可分割的最小单位,又称数据域,数据元素是数据项的集合。
**数据对象:**是指具有相同性质的数据元素的集合,是数据的子集。
**数据结构:**是吧成员组织到一起的方式,是一以数据为成员的结构,是带结构的数据元素的集合,数据元素之间存在一种或多种的关系。
**结点:**数据结构中的数据元素称为结点。
**数据处理:**指对数据元素进行处理的方式,包括对数据的插入、删除、查找、更新、排序等操作,也包括对数据元素进行分析的操作。

数据结构是研究计算机的操作对象以及它们之间的关系和操作等的学科,目的是提高计算机的数据处理效率并节省存储空间。
数据结构主要研究三方面的内容:**数据的逻辑结构、数据的存储结构和数据结构的操作。**

**抽象数据类型:**ADT是指一个数学模型以及定义在此数学模型上的一组操作,ADT是与具体的物理存储无关的数据类型,因此无论ADT的内部结构如何变化,只要其数据结构的特性不变,都不影响其外部使用。

**【算法基础】**
**算法:**是有限的步骤内解决数学问题的过程,是以一步一步的方式来详细描述计算机如何将输入转化为所要求的输出的过程,即对计算机上执行的计算过程的具体描述。其包含5个特性即:**有穷性、确定性、输入、输出和可行性。**;而算法应具备**正确性、可读性和健壮性。**

算法分析问题主要研究时间代价和空间代价,一把通过复杂度来进行评价:
**时间复杂度:**一个算法所耗费的时间应当是该算法中每条语句的执行时间之和,而每条语句的执行时间就是该语句的执行次数与该语句的执行一次所需的时间的积。因此一个算法的时间复杂度可有=由问题规模的函数来表示,即一个算法的时间代价是由该算法用于问题规模为n的实例所需的基本操作次数来确定,一般用T(n)来表示算法的基本计算次数即算法的时间复杂度。以**O(n)**表示法为例,一般来说,计算机算法的时间复杂度是问题规模n的函数f(n),如果存在正的常数c和n0,当问题的规模n>=n0时,算法的时间复杂度**T(n)<=c·f(n)**,则该算法的时间(空间)复杂度为**O(f(n)),记为:T(n)=O(f(n))**,其运算需要具体看书,此处无法系统概述。
**空间复杂度:**算法在计算机内执行时所需要存储空间的度量。分析与时间复杂度类似。

**【算法设计】**
算法主要包括:递推法、递归法、穷举法、迭代法、分治策略、贪心策略、动态规划策略、回溯策略和分支界限策略等,将在后续博客开始介绍。

**此处主要简单介绍一下动态规划策略:**
    动态规划与贪心策略类似,将一个问题划分为重复的子问题,通过对相同子问题的求解来解决较大问题,即将一个问题的解决方案视为一系列决策的结果。不同的是在贪心策略中每采用一次谈心策略便做出一个不可撤回的决策,肯能得不到最优解;而动态规划处理要求按照某中规则进行选择,还要考察每个最优决策序列中是否包含一个最优子序列,目的是得到问题的最优解。
    动态规划的基本思想是如果能保存已解决的子问题的答案,就可以避免大量重复计算,当要解决的问题是相同的子问题时,重用已保存的结果即可,从而得到多项式时间算法。方式包括**自顶向下和自下而上的方法**,即将问题划分为子问题和通过求解子问题从而组合成总问题的解。其中**自顶向下**的递归方法又叫备忘录方法,即需要记录子问题的结果以满足当需要解决相同子问题的时候直接使用结果。
    以斐波那契数列的生成为例,介绍三种方法:
    递归法:
 

int fib(int n){
    if(n==1||n==2){
        return 1;
    }
    else{
        return fib(n-1)+fib(n-2);
    }
}


    
自下而上:
 

int fib(int n){
    int i,f1=f2=1;
    for(i=3; i<=n; i++){
        f=f2;
        f2=f+f2;
        f1=f;
    }    
}


自顶而下:(备忘录)
 

int fib(int n){
    int memo[n+1];
    for(int i1;i<n+1;i++){
        memo[i]=0;//初始化
    }
    
    int f1,f2;
    if(n==1||n==2){
        return 1;
    }
    if(memo[n-2]==0){
        f1=fib(n-2);
    }
    else{
        f1=memo[n-2];
    }
    if(memo[n-1]==0){
        f2=fib[n-1];
    }
    else{
        f2=memo[n-1];
    }
    memo[n]=f1+f2;
    
    return f1+f2;
}


可见,自下而上的方法是非常快速的,因为计算机的CPU就是在计算上会耗费大量时间,因此减少计算就一定程度上可以减少时间复杂度。而对比递归法和自顶向下的方法来看:递归法需要在每次函数调用中会计算大量的重复内容,导致大量的重复计算工作;而自顶向下(备忘录)方法就存储了子问题的结果,当需要计算相同子问题的值时就先访问存结果的数组,看是否已经有子问题的解,如果有就直接使用,这样就避免了重复计算,是典型的空间换时间的例子。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值