数据结构——第一章:绪论

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weijunqiang1224/article/details/102747687

学习目标:

  1. 了解并理解数据,数据元素,数据结构,逻辑结构,存储结构,算法及算法设计-分析-时间复杂度等知识点。

1、绪论

一、数据结构的概念及其内容

        数据结构是带有结构的数据元素的集合,其中的结构是指数据元素之间的相互关系,即数据的组织形式。

       数据(data):描述客观事物的数,字符以及能输入计算机中并被计算机处理的符号的集合。如:整数,实数,字符串,当然也可以是图像,图形,声音等都属于数据。

       数据元素(data element):是数据的基本单位。数据元素可以由若干个数据项(字段,域,属性)组成;数据项是具有独立含义的最小标示单位,如图书中的 作者,书名,编码等

       数据对象(data object):是具有相同性质的数据元素的集合,是数据的一个子集。

      即:数据 》 数据对象 》 数据元素 》 数据项(可理解数据库的 一张 表 》 记录(行数)》 单行记录 》行记录中的字段属性(行一列) )

       数据结构,一般包括三方面:数据的逻辑结构、数据的存储结构(物理结构)以及数据的运算(数据元素的操作)。

程序 = 数据结构 + 算法(此处的数据结构即指:逻辑结构+存储结构;此处的算法即指:对数据运算的描述)

在实际问题解决中,要考虑好数据结构以及算法;好的数据结构以及好的算法可以取得问题最优的解决时间复杂度。

例如:隔壁老王有100块钱,要买一百只鸡,其中公鸡 5 块钱一只,母鸡 3 块钱一只,小鸡 一块钱 3只,求公鸡,母鸡,小鸡各买了多少只鸡。我们可以设公鸡买了 x 只,母鸡买了y只,小鸡买了 z只。则有以下方程式:

  • x + y + z         = 100
  • 5x + 3y + z/3 = 100
  • z % 3              = 0

那么可以有算法:

//函数返回值满足问题的解数(即多少组结果),g[],m[],s[]分别存放公鸡,母鸡,小鸡的个数

算法一:

int chicken_question(int g[], int m[], s[]) {
    int x, y, z, k = 0;
    
    for (x = 0; x <= 100; x++)
        for (y =0; y <= 100; y++)
            for (z = 0; z <= 100; z++) 
                if ( (x + y + z == 100) && (5*x + 3*y + z/3 == 100) 
                     && (z % 3 == 0) ) {
                    g[k] = x;
                    m[k] = y;
                    s[k] = z;
                    k++;
                }

     
    return k;
}

上面的算法:最终计算得出了 k组结果,即结果集为:{(g[0],m[0], s[0]),.....(g[k-1],m[k-1], s[k-1])}, k>0;

而为了计算这简单的问题,计算机居然执行了,101 * 101 * 101次,即时间复杂度为O(101^3),达到上百万次,这是绝对不能允许的,算法设计太低效的了。

求解一个问题可能有许多种不同的算法,而算法的好坏直接影响到程序的执行效率,不同算法之间的运算效率相差巨大!所以,

我们可以继续分析该问题:购买的鸡数范围为:公鸡 x :[0, 20],母鸡 y: [0, 33], 小鸡 z: 100 - x - y, 那么我们可以重新设计算法:

算法二:

int chicken_question(int g[], int m[], s[]) {
    int x, y, z, k = 0;
    
    for (x = 0; x <= 20; x++)
        for (y =0; y <= 33; y++)
            z = 100 - x - y; 
            if ( (5*x + 3*y + z/3 == 100) && (z % 3 == 0) ) {
                g[k] = x;
                m[k] = y;
                s[k] = z;
                k++;
            }

     
    return k;
}

上面的算法:最终计算得出了 k组结果,即结果集为:{(g[0],m[0], s[0]),.....(g[k-1],m[k-1], s[k-1])}, k>0;

经过优化后的算法,计算机最终只执行了,21 * 34次,即时间复杂度为O(21 * 34),只有714次,远小于算法一的执行时间。

算法的五要素:输入,输出,有穷性,确定性,可行性。

 通过上面两个算法,我们明白首先要得到问题的答案,即算法必须是正确的(上面的方程组);而后再考虑算法执行所耗费的时间,即时间复杂性;执行算法所耗费的存储空间,主要是辅助空间,即空间复杂性;算法还要尽量保证易于理解,易于编程,易于调试,即可读性和可操作性。

其中时间复杂性,即表示一个算法所耗费的时间应该是算法中每条语句执行的时间只和,而每条语句的执行时间就是该语句执行的次数(或频度)与该语句执行一次所需时间乘积。而由于各种计算机对相同算法语句执行的时间可能不同,所以一般不作为统一的量来衡量。 而一般情况下,算法中的基本操作重复执行的次数是问题规模n的某个函数f(n),算法的时间量度记为: T(n) = O(f(n)).

常用的计算算法时间的多项式(时间复杂性递增排列):常数阶O(1) < 对数阶O(log2^n) < 线性阶O(n) < 线性对数阶O(nlog2^n) < 平方阶O(n^2) < 3次方阶O(n^3) .... < k次方阶O(n^k) < 指数阶O(2^n) < 阶乘阶O(n!)

二、数据结构在逻辑上的分类

        从逻辑上,数据结构又分为:线性结构 、非线性结构 两大类。

线性结构特点:数据元素(节点)之间存在一对一的关系,且结构中只有一个开始节点,一个终端节点,其余节点都是仅有一个直接前驱(趋)和一个直接后继。而开始节点没有直接前驱(趋),终端节点没有直接后继。

非线性结构特点:数据元素之间存在着一对多或者多对多的关系,即一个节点可能有多个直接前驱和多个直接后继。如:树形结构, 图形结构,网状结构。

、数据结构在存储上的分类

        数据元素及其关系在计算机内的存储方式,即为数据的存储结构(物理结构)。如果向量中各元素按其逻辑关系“顺序”存储,则为 顺序存储结构;向量中各元素是通过指针连接存储在内存中,则为 链式存储结构。数据的存储结构是数据在计算机中的存储表示(映像),也称为数据的物理结构。数据的存储结构可用以下四种基本的存储方法实现:

  1. 顺序存储方法:节点连续,存储单元连续
  2. 链接存储方法:节点连续,存储单元可能不连续
  3. 索引存储方法:存储元素信息还需建立附加的索引表(关键字,地址);关键字是能唯一标识一个元素的一个数据项或多个数据项的组合
  4. 散列存储方法:根据元素的关键字直接计算出该元素的存储地址

下篇:数据结构——第二章 线性表

猜你喜欢

转载自blog.csdn.net/weijunqiang1224/article/details/102747687