数据结构与算法(一),概述

转载请注明出处:http://www.cnblogs.com/wangyingli/p/5919297.htmlhtml

数据结构学了有一年的时间了,可是一直没有好好的总结一下,如今回想起来,感受好像都不怎么记得了。因此接下来一段时间我将从新学习一下,算是温故而知新了。本着「分享是一种美德」的精神,我将把个人学习总结记录下来,并与你们分享。java

本节的主要内容有:算法

  • 1、数据结构
    • 一、定义
    • 二、关于数据结构的几个术语
    • 三、逻辑结构与物理结构
  • 2、抽象数据类型
  • 3、算法
  • 4、算法的复杂度
    • 一、时间复杂度
    • 二、空间复杂度

1、数据结构

一、定义

数据结构是计算机存储、组织数据的方式。在现实世界中,不一样数据元素之间不是独立的,而是存在特定关系的,咱们将这些关系称为结构。一样在计算机中,数据元素也不是孤立、杂乱无序的,而是具备内在联系的数据集合。编程

数据元素之间存在的一种或多种特定关系,也就是数据的组织形式,叫数据结构。也能够说,数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。数组

一般状况下,精心选择的数据结构能够带来更高的运行或者存储效率。程序设计的实质就是数据结构和算法是设计,所以咱们说程序设计 = 数据结构 + 算法数据结构

二、关于数据结构的几个术语

  • 数据:是描述客观事物的符号,是计算机中能够操做的对象,是能被计算机识别,并输入给计算机处理的符号集合。它不只包括整型等数值类型,还包括字符、声音、图像等非数值类型。这些类型都具有两个特征:
    • 能够输入计算机
    • 能被计算机程序处理
  • 数据元素:是组成数据的、有必定意义的基本单位,在计算机中一般做为总体处理。也被称为记录。并发

  • 数据项:一个数据元素能够由若干个数据项组成。数据项是A数据的不可分割的最小单位。。数据结构和算法

  • 数据对象:是性质相同的数据元素的集合,是数据的子集。编程语言

例如:一本书的书目信息为一个数据元素,而书目信息的每一项(如书名、做者名等)为一个数据项。模块化

三、逻辑结构与物理结构

按照不一样的角度,数据结构可分为逻辑结构和物理结构。其中逻辑结构是面向问题的,而物理结构是面向计算机的,它们的基本目标都是将数据及其逻辑关系存储到计算机内存中。

  • 逻辑结构:是指数据对象中数据元素之间的相互关系。分为四种:集合结构、线性结构、树形结构和图形结构。

四种逻辑结构

  • 物理(存储)结构:是指数据的逻辑结构在计算机中的存储形式。数据的存储结构应正确反映数据元素之间的逻辑关系,这是关键。数据元素的存储结构可分为两种:顺序存储结构和链式存储结构。
    • 顺序存储结构:把数据元素放在地址连续的存储单元中,数据间的逻辑关系和物理关系一致。如,数组。
    • 链式存储结构:把数据元素放在任意的存储单元中,数据间使用指针关联。数据元素的存储关系不能反映其逻辑关系。如,链表。

2、抽象数据类型

数据类型是指一组性质相同的值的集合及定义在该集合上的一些操做的总称。而抽象是指抽象出事物具备的广泛性的本质,它是抽出问题的特征而忽略非本质的细节,是对具体事物的一个归纳。抽象隐藏了繁杂的细节,只保留实现目标所必须的信息。所以抽象数据类型能够定义为:

抽象数据类型(Abstract Data Type,ADT)是指一个数学模型及定义在该模型上的一组操做,它是一种向用例隐藏内部表示的数据类型。

面向对象编程的特征之一就是使用数据类型的实现封装数据,以简化实现、隔离用例开发、实现模块化编程。抽象数据类型体现了程序设计中问题分解、抽象和信息隐藏的特性。它将实际生活中的问题分解为多个规模小、可以独立开发和调试的小型模块,而后进行独立编程。这种方式将代码的影响限制在局部区域,改进了咱们的软件质量,促进了代码复用。抽象数据类型抽象的层次越高,那么可复用性也越强。好比:java中的Object是对全部对象的抽象。

java中数据类型能够分为两类:

java数据类型

  • 基本(原子)类型:不能够再分解的基本类型,包括int、short、long等
  • 引用(结构)类型:由其余类型组合而成,能够再分解。如,String、数组等

注意:

  1. 对原子类型的操做不必定是原子操做,这点并发编程时应特别注意。如,在32位机上对long类型的操做就不是原子操做,由于其高32位和低32位是分别存储的。
  2. Java中全部的基本数据类型都有固定的存储范围和大小,其不受具体机器和操做系统的影响。

3、算法

算法(Algorithm)一词最先出如今波斯数学家al-Khwarizmi所写的《印度数字算术》中。欧几里得算法(求两个整数的最大公约数)被认为是史上第一个算法。

算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,而且每条指令表示一个或多个操做。

算法的基本特性:

  • 输入输出,算法具备零个或多个输入,至少有一个或多个输出。
  • 有穷性,算法在执行有限步后可以自动结束,不会出现无限循环。
  • 肯定性,算法的每一步都具备肯定的含义,不会出现二义性。
  • 可行性,算法的每一步都可以经过执行有限次操做完成。

程序与算法的区别:

程序(program)是软件开发人员根据用户需求开发的、用程序设计语言描述的适合计算机执行的指令(语句)序列。它包括「数据结构」、「算法」、「程序设计方法」和「编程语言」。程序是算法用某种程序设计语言的具体实现。程序能够不知足算法的有穷性,好比操做系统也是一种程序,它能够一直运行。

算法的设计要求:

  • 正确性,算法至少应该具备输入、输出和加工处理无歧义、能正确反映问题的需求、可以获得问题的正确答案。
  • 可读性,便于阅读、理解和交流。
  • 健壮性,输入不合法时,算法可以给出相应的处理,而不是产生错误的结果。
  • 高效性,算法应该尽可能知足高效率和低存储的需求。

4、算法的复杂度

算法复杂度分为时间复杂度和空间复杂度。其做用: 时间复杂度是指执行算法所须要的计算工做量;而空间复杂度是指执行这个算法所须要的内存空间。

一、时间复杂度

算法的时间复杂度反映了算法执行的时间长短,它是度量一个算法好坏的重要指标。

通常状况下,算法中基本操做重复执行的次数是问题规模n的某个函数,用T(n)表示,如有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记做T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。

度量一个算法的时间复杂度一般有两种方式:

  • 过后统计法
  • 事前分析法(大O表示法)

算法的时间复杂度是由最深层嵌套语句的频度决定的。

大O表示法的推导:

  1. 用常数1取代运行时间中的全部加法常数
  2. 在修改后的运行次数函数中,只保留最高阶
  3. 将最高阶系数变为1

例1:

int i, j, temp;
for(i=0; i<n; i++) {
    for(j=i, j<n; j++) {
        temp++;
    }
}

语句执行的总次数:
\[ T(n) = n+(n-1)+(n-2)+\cdots+1 =\frac{n(n+1)}{2} = \frac{n^2}{2} + \frac{n}{2} \]
因此其时间复杂度为\(O(n^2)\)

例2:

for(i=1;i<=n;i=i*2){
   System.out.println(i);
}

执行的总次数知足:
\[2^{T(n)} <= n\]
\[T(n)=log_2n = Clogn\]
因此它的时间复杂度为\(O(logn)\)

例3:分析冒泡排序算法的时间复杂度

//冒泡排序算法
public static void bubbleSort(int[] data) {

    if (data == null) {
        return;
    }
    int temp = 0;
    for (int i = data.length - 1; i > 0; --i){
        for (int j = 0; j < i; ++j){
            if (data[j + 1] < data[j]){
                temp = data[j];
                data[j] = data[j + 1];
                data[j + 1] = temp;
            }
        }
    }
}

算法分析:

  • 最佳状况下(初始状态是正序时),冒泡排序算法只须要一次扫描便可完成排序,此时比较次数 \(C_{min} = n - 1\),移动次数 \(M_{min} = 0\),因此时间复杂度为 \(O(n)\)
  • 最差状况下(初始状态为逆序时),须要进行 \(n-1\) 次排序,每次排序进行 \(n-1\) 比较,此时比较次数 \(C_{max} = \frac{n(n+1)}{2}\),移动次数 \(M_{max} = \frac{3n(n+1)}{2}\),因此时间复杂度为\(O(n^2)\)

常见时间复杂度大小关系:
\[O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)\]

算法的时间复杂度和两个因素有关:算法中的最大嵌套循环层数;最大嵌套循环结构中每次循环的次数。通常来讲,具备多项式时间复杂度的算法是能够接受的;具备指数时间复杂度的算法,只有当n足够小时才可使用。通常效率较好的算法要控制在O(N)或者O(log2 N)

二、空间复杂度

空间复杂度(Space Complexity)是对一个算法在运行过程当中临时占用存储空间大小的量度,记作S(n)=O(f(n))。其中,n为问题规模,f(n)为语句关于n所占存储空间的函数。

算法的空间复杂度分析方法和算法的时间复杂度分析方法基本相同。

例如:

int i, j, temp;
for(i=0; i<n; i++) {
    for(j=i, j<n; j++) {
        temp++;
    }
}

上方代码中,仅需为变量 i、j、temp分配空间便可,因此空间复杂度 \(S(n) = O(1)\)

参考

相关文章
相关标签/搜索