重学数据结构篇1- 基本概念与算法

Posted adventure.Li

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重学数据结构篇1- 基本概念与算法相关的知识,希望对你有一定的参考价值。

–课程内容

  • 什么是数据结构
  • 抽象数据结构类型以及面向对象概念
  • 模板
  • 算法定义
  • 算法性能分析与度量

–重点要求

  • 数据结构概念以及相关术语
  • 数据结构的三要素:逻辑结构、物理结构、数据运算
  • 算法时间复杂度和空间复杂度的分析与计算

一、什么是数据结构

  1. 信息、数据、数据元素、数据对象、数据类型是什么?

信息:信息,指音讯、消息、通讯系统传输和处理的对象,泛指人类社会传播的一切内容。

数据:数据是信息的载体(可理解为信息的具体化表示),是描述事物的数、字符、以及所有能输入到计算机中并被计算机识别处理的符号的集合。

由定义可知,数据在计算机中可以分为两类,即数值数据(Java中对应八大基本数值类型)和非数值性数据(字符、图像、图形、文件、文本(html、WORD、PPT、EXLS)、视音频)。而计算机中最根本的则是二进制数据,对应高低电平表示(计算机网络中信息传输也是通过数字信号或模拟信号进行01表示传输),所以对于高级的数据(音视频)需要进行编码处理转换。

数据元素:数据的基本单位
数据对象:数据的子集,具有相同性质的数据成员(数据元素)的集合。例如 整数数据对象 N={0,1,2},学生数据对象
可以理解为面向对象编程中设计的类(Java中的对象)
数据类型:一个值的集合和定义在此集合上的一组操作的总称。(可以分为原子数据类型、结构类型、抽象数据类型)
Java中分为 基本数据类型和引用数据类型

  1. 数据结构的定义?

由某一数据对象以及该对象中所有数据成员之间的关系组成。
另外一种说法:相互之间存在一种或多种关系数据元素的集合。

Data_Structure = {D, R}
首先,需要明白数据结构针对的对象是数据对象(含有相同的数据元素),因此在编程语言中的 数组并不是数据结构,他是一个线性结构,物理内存的表示。其次,需要掌握该数据对象之间的关系

  1. 数据结构三要素

逻辑结构:数据元素之间的逻辑关系

存储结构:数据元素以及关系在计算机存储中的表示

数据的运算:对数据元素施加的操作

一个算法的设计取决于所选定的逻辑结构,而算法的实现依赖所用的存储结构。

在这里插入图片描述
二、 抽象数据类型及面向对象概念

  1. 抽象数据类型

由用户定义,用以表示应用问题的数据模型
由基本的数据类型组成, 并包括一组相关的服务(或称操作)
信息隐蔽和数据封装,使用与实现相分离
抽象数据类型可用(D, S, P)三元组表示,其中,D 是数据元素的集合(简称数据对象),S 是 D上的关系集合,P 是对 D 的基本操作集合。

三、模板

适合多种数据类型的类定义或算法,在特定环境下通过简单地代换,变成针对具体某种数据类型的类定义或算法。
关于Java的泛型写法参考菜鸟网站之Java泛型

四、算法的定义

定义:是对特定问题求解步骤的一种描述,算法是指令的有限序列,其中每一条指令表示一个或多个操作。

特性:输入、输出、有穷性、确定性、有效性

例:选择排序的设计

策略: 自顶向下,逐步求精

  1. 先思考解决问题的思路,当大脑确定正确无误后进行第二步(排好前i个数,当排i+1个数时则选取剩下的n-i个数中的最小数排列)
  2. 设计框架
//初始值a[k] 
for ( int i = 0; i < n-1; i++ ) {    //n-1趟      	从a[i]检查到a[n-1];	若最小的整数在a[i], 交换a[i]与a[k]; }
  1. 细化程序
void selectSort ( int a[ ], const int n ) {
 //对n个整数a[0],a[1],…,a[n-1], 按非递减顺序排序
       for ( int i = 0; i < n-1; i++ ) {
            int k = i;
            //从a[i]检查到a[n-1], 找最小的整数, 在a[k]
            for ( int j = i+1; j < n; j++ )
 	     if ( a[j] < a[k] ) k = j;	
	          //k指示当前找到的最小整数
            int temp = a[i];  a[i] = a[k];   a[k] = temp;
                     //交换a[i]与a[k] ->将该位置的数换出去,并将适合该位置的数放进来
        }
 }	

五、算法性能分析

  1. 正确性

四个层次:
程序不含语法错误;
程序对于几组输入数据能够得出满足规格说明要求的结果;
程序对于精心选择的典型、苛刻而带有刁难性的几组输入数据能够得出满足规格说明要求的结果;
程序对于一切合法的输入数据都能产生满足规格说明要求的结果。

  1. 可使用性
  2. 可读性(注意写注释)
  3. 健壮性(健壮性一般指鲁棒性。鲁棒是Robust的音译,也就是健壮和强壮的意思。它也是在异常和危险情况下系统生存的能力。比如说,计算机软件在输入错误、磁盘故障、网络过载或有意攻击情况下,能否不死机、不崩溃,就是该软件的鲁棒性)
  4. 效率

分析方法:事前估计、事后测试

六、算法复杂度的度量

空间复杂度的度量

一般算法在执行期间所需要的存储量应该包括以下3个部分:
(1)输入数据所占用的空间
(2)程序代码所占用的空间
(3)辅助变量所占用的空间

时间复杂度的度量

程序步
语法上或语义上有意义的一段指令序列
执行时间与实例特性无关

注释:程序步数为0
声明语句:程序步数为0
表达式:程序步数为1, return a+b+b*c

例:以迭代方式求累加和的函数(插入计数全局变量count确定程序步)

 float sum ( float a[ ], const int n )
 1    {
 2       float s = 0.0;
 3       for ( int i = 0; i < n; i++ )
 4           s += a[i];			
 5       return s;
 6    }	
float sum ( float a[ ], const int n )	{
       float s = 0.0;
       count+2;	//count统计执行语句条数
       for ( int i = 0; i < n; i++ ) {
           count+2;	//针对for语句
	 s += a[i];
	 count++;
       }	//针对赋值语句
       count+2;	//针对for的最后一次
       count++;	//针对return语句
       return s;

一个语句本身的程序步数可能不等于该语句一次执行所具有的程序步数。
在这里插入图片描述
时间复杂度大小:
c< log2n < n < nlog2n < nn < nn*n < 2^n
< 3^n < n!

算法设计练习

  1. 选择排序
 <E> void selectSort(E[] arr ,Comparator<E> comparator){
        // 选择排序,数据为数值型
        for(int i=0;i<arr.length;i++){
            // 对第i个位置进行选取数
            int temp = i;
            for(int j=i;j<arr.length;j++){
                if(comparator.compare(arr[j], arr[temp])<0)//arr[j]<arr[temp]
                    temp=j;
            }
            E t = arr[temp];
            arr[temp]=arr[i];
            arr[i]=t;
        }
    }

    public static void main(String[]args){
        Integer[] arr = {4,2,3,9,1,7,0,12};
        new Chapter1().selectSort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.intValue()-o2.intValue();
            }
        });
        for(Integer i:arr)
            System.out.println(i);

    }
  1. 编写算法,计算i!*2^i的值并存入数组a[arrsize]的各个分量,假设允许的最大整数为MAXINT,则当n>arrisize或k!*2 ^k>MAXINT,应该出错处理
 int MAX_INT = Integer.MAX_VALUE;
    void compute(int []arr,int n){
        arr = new int[n];
        arr[0]=1;
        for(int i=1;i<n;i++){
            if(arr[i-1]*2*i>MAX_INT||arr[i-1]*2*i<0)
                exit(-1);
            else
                arr[i]=arr[i-1]*2*i;
        }
        for(int i=0;i<n;i++)
            System.out.println(arr[i]);
    }

以上是关于重学数据结构篇1- 基本概念与算法的主要内容,如果未能解决你的问题,请参考以下文章

《重学数据结构与算法》:请手写一个简易的单链表

《重学数据结构与算法》:请手写一个简易的单链表

重学数据结构栈与队列

重学数据结构篇2 上线性表之基础知识

重学C++

重学数据结构与算法