数据结构 第一章绪论笔记

绪论

数据结构的创始人:
1938年12月7日,Donald E. Knuth 出生于美国威斯康星州密尔沃基市。其父是个中学教师,经常在星期天到教堂演奏管风琴,小 Knuth 耳濡目染,日后也成为教师,业余爱好也是弹管风琴。1938年12月7日,Donald E. Knuth 出生于美国威斯康星州密尔沃基市。其父是个中学教师,经常在星期天到教堂演奏管风琴,小 Knuth 耳濡目染,日后也成为教师,业余爱好也是弹管风琴。

1. 数据结构的组成

  数据结构的最基本组成可以使用二元数组表示,即data_structure={D,R},其中,D为数据元素的集合,R为根据数据间关系形成的结构的集合。我们也可以采用四元数组表示一种数据结构,即data_structure={D,L,S,O},相当于我们将数据结构分成逻辑结构和存储结构两部分,并规定了可对数据进行的运算。

1.1 逻辑结构

   逻辑结构即数据之间的“关系”,通常有线性结构、树形结构、图形结构和集合结构。

逻辑结构 特点
线性结构 一对一
树形结构 一对多
图形结构 多对多
集合结构 松散
1.2 存储结构

存储结构 特点
顺序存储 通常使用数组,地址计算L(i)=L0+(i-1)*m,访问速度快,查找快。
链式存储 元素结构之间无需直接相邻,每个结点存储了data和point(指向下一个元素的地址),节约空间且灵活。

对数据元素的基本操作:查找、插入、删除、遍历和排序。

2.数据结构的算法及算法分析

    1. 什么是算法?

算法是利用计算机解决问题的处理步骤,简而言之,算法就是解决问题的步骤。

算法不仅仅用于计算机的数据处理,现实世界中的各种问题也需要结合算法的概念来解决,

    1. 为什么要学习算法?

学习算法的同时能提高自己的编程能力。一个好的算法是编写程序的模型,因为它能创造计算机程序,其中还包含了程序的精髓。学过算法的人写出的程序和没学过算法的人写出的程序有明显的差距。要写出既能正确执行又能提高效率的好程序,算法的学习是不可或缺的。

算法的学习类似于学习游戏攻略,有了攻略就能轻松取得游戏的成功。

    1. 怎么样的解决问题方案才称为算法?
  • 算法必须满足的五个重要特性:

输入 输出 有穷性 确定性 可行性

  • 算法必须具备两个重要条件:

有效性:算法必须要为给定的任务给出正确的结果,即,有满足条件的输入值时,此算法一定要保证正常工作(返回正确的输出值)。表明算法有效性的方法之一就是断点。断点设置在算法的任意位置上,判断此位置是否满足给出的条件,即,程序是否正确运行。

终止性:算法中没有永远反复执行,即,没有无限循环,且不返回答案的情况。算法终止性可以用反复处理结束条件的判断变量,或经过有限次的反复一定能到达结束条件等方法证明。

    1. 算法的基础——结构化程序设计的思想

用计算机编写程序时,为了提高应用程序的效率,把设计上的错误最小化,有一种编程思想叫做结构化程序设计。

结构化程序设计中所有的处理流程,可以用以下三种结构组合而成:

顺序结构:按照所述顺序处理
  选择结构:根据判断条件改变执行流程
  循环结构:当条件成立时,反复执行给定的处理操作
  
求最大公约数的代码

int CommonFactor(int m,int n)
{
r=m%n;
while(r!=0)
{
m=n;
r=m%n;
}
return 0;

}

2-5. 算法的分析
算法的时间复杂度
  (1)语句频度T(n): 一个算法执行所花费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。而且一个算法花费的时间与算法中的基本操作语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度,记为T(n)。

(2)时间复杂度: 在刚才提到的语句频度中,n称为问题的规模,当n不断变化时,语句频度T(n)也会不断变化。但有时我们想知道它的变化呈现什么规律。为此,我们引入时间复杂度概念。 一般情况下,算法中的基本操作语句的重复执行次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n) / f(n) 的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作 T(n)=O( f(n) ),称O( f(n) ) 为算法的渐进时间复杂度,简称时间复杂度。
  T(n) 不同,但时间复杂度可能相同。 如:T(n)=n²+5n+6 与 T(n)=3n²+3n+2 它们的T(n) 不同,但时间复杂度相同,都为O(n²)。
(3)常见的时间复杂度有:常数阶O(1),对数阶O(log2n),线性阶O(n),线性对数阶O(nlog2n),平方阶O(n2),立方阶O(n3), k次方阶O(nk),指数阶O(2n)
算法的空间复杂度  
  空间复杂度(Space Complexity) 是对一个算法在运行过程中临时占用存储空间大小的量度,记做 S(n)=O(f(n)) ,其中n为问题的规模。利用算法的空间复杂度,可以对算法的运行所需要的内存空间有个预先估计。
  一个算法执行时除了需要存储本身所使用的指令、常数、变量和输入数据外,还需要一些对数据进行操作的工作单元和存储一些计算所需的辅助空间。算法执行时所需的存储空间包括以下两部分。  
(1)固定部分。这部分空间的大小与输入/输出的数据的个数、数值无关。主要包括指令空间(即代码空间)、数据空间(常量、简单变量)等所占的空间。这部分属于静态空间。
(2)可变空间,这部分空间的主要包括动态分配的空间,以及递归栈所需的空间等。这部分的空间大小与算法有关。
举例分析算法的空间复杂度:

 public void reserse(int[] a, int[] b) {
        int n = a.length;
        for (int i = 0; i < n; i++) {
            b[i] = a[n - 1 - i];
        }
    }

上方的代码中,当程序调用 reserse() 方法时,要分配的内存空间包括:引用a、引用b、局部变量n、局部变量i

因此 f(n)=4 ,4为常量。所以该算法的空间复杂度 S(n)=O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值