Skip to content

Latest commit

 

History

History
133 lines (84 loc) · 6.59 KB

从零开始学习数据结构_入门篇.md

File metadata and controls

133 lines (84 loc) · 6.59 KB

校招找工作的时候,我学的最好的就是 C 语言和数据结构了,每次面试都会问到这块,尤其是数据结构的考察,这是我的一大亮点,你非要我选择最拿的出手的技术栈,当年非是数据结构莫属了。

数据结构 + 算法,是校招面试必问的,是能进互联网大厂的必要条件,大二、大三在学习的时候,一定要有这个意识。

一、如何学习

对于数据结构的学习,一定要搞清楚每一种结构,只懂原理远远不够,需要敲代码去实现,这才是真正的掌握,跟着我这个专栏走,每一种数据结构都是有代码实现的。

数据结构的学习不仅仅是原理,是代码实现,这仅仅是基础要求,更深层次的是打破知识体系之间的独立性、隔离性,以及在面对复杂问题的时候,你是怎么看待不同数据结构的,这就要求你知其然,更要知其所以然,这才是融会贯通、学以致用!

怎么理解我上面说的打破知识体系的独立性、隔离性?如果你不懂数据在真实内存中的存储方式,不懂内存是一维、线性、不懂虚拟内存、真实物理空间,这些操作系统中的相关知识,你学到的只是死记硬背,应付面试而已,无法真正掌握数据结构的精髓;当你碰到实际工程上面的问题时,你就会傻眼,明明学过的知识,却不会迁移到实际的业务中,这就是在学习的时候缺乏思考,多问自己几个为什么?只有真正掌握了本质、原理,你才能灵活运用、得心应手。

如果代码实现有困难,那就看我的代码,把它吃透吸收下来,对于每一种数据结构的实现,我都会把代码放到这里,充分体现面向对象的思想,面向提供工具的思想。

真的不用太纠结是什么语言实现的,要聚焦关心其原理,每种数据结构的特点,什么场景下使用合适?能解决什么问题?

可能我上面说到的这段话,你暂时无法理解,而真正实际面临的复杂问题,都是通过更为复杂的数据结构进行解决的,随着不断的深入学习,我相信你对于数据结构的认知会越来越不一样(越复杂的数据结构,其应用面是越广的,因为能真正解决工程上面的问题,图是比较复杂的数据结构:应用在知识图谱、图索引等场景中)。

数据结构 + 算法资料推荐:算法成神之路

二、数据结构

软件 = 数据结构 + 算法 + 软件环境

数据结构 = 数据 + 结构 + 算子(运算、函数)

2.1 数据结构三要素

  • 数据;
  • 数据结构:数据间关系;指的是线性关系和非线性关系;或者说一对一关系,一多关系,多多关系;
  • 数据结构上的运算:在其基础上进行的一系列相关运算;

2.2 逻辑结构 + 物理结构

逻辑结构:存在于思想中,是看不见摸不着;分为线性逻辑结构与非线性逻辑结构;

物理结构:内存存储的真实结构;分为物理线性结构(数组)和物理非线性结构(链表);

2.3 核心数据结构

  • 线性结构:线性表、堆栈、队列、数组、矩阵、串;
  • 非线性结构:链表、树、二叉树、图(了解);

三、算法

  • 算法:又被叫为算子,是实现一个问题的方法;
  • 算法五大特点:确定性、正确性、有效性、有穷性、有输出;
  • 衡量算法优劣性方法:时间复杂度 + 空间复杂度;

3.1 时间复杂度

是问题规模与完成该问题所需要的基础操作步骤数量的函数关系(不是指运行多少时间,一般指的是最差情况下的时间复杂度)

例:数组 array 长度为 count,在其中查找值为 key 元素的下标。

#define NOT_FOUND -1

int findKey(int *array, int count, int key) {
    int index = 0;

    while(index < count && array[index] != key) {
        index++;
    }

    return index >= count ? NOT_FOUND : index;
}

核心分析:

上面这个例子查找算法的基础操作是:array[index] != key。

  • 总比较次数:1 + 2 + 3 + ... + n = (1+n)/2
  • 总查找次数:n

那么,每一次查找所比较的次数是:((1 + n) * n / 2) / n = (1 + n) / 2

n 表示数据规模,那么这个查询算法的时间复杂度是 O((1 + n) / 2);当 n 趋于无穷大时,那么:O((1 + n) / 2) <==> O(n),等价关系,即该查找算法时间复杂度为 O(n)。

一定要明确时间复杂度的计算方式,以及自己会评估算法的时间复杂度,是算法基础功,这个知识点在面试中必问,一定要掌握(常见面试问题:二分查找)。

3.2 空间复杂度

任务规模与实现该任务所需要的辅助存储空间大小之间的函数关系。

例:数组 array 长度为 count,实现该数组的逆序。

void reverseArray(int *array, int count) {
    int i;
    int *tmp;

    tmp = (int *)malloc(sizeof(int), count);
    for (i = count-1; i >= 0; i--) {
        tmp[i-count+1] = array[i];
    }
    for (i = 0; i < count; i++) {
        array[i] = tmp[i];
    }

    free(tmp);
}

核心分析:

上面这个例子逆转数组的基础操作是:tmp = (int *)malloc(sizeof(int), count);

申请了跟原先数组一样大的辅助空间,即空间复杂度为:O(n);串行遍历了数组 2 次,这个时间复杂度为:O(2n);

四、学习思维

数据结构+算法学习思维:

  1. 数据结构 + 算法与具体程序设计语言无关!(C++、Java、Go、Python等等都可以);
  2. 提供给他人进行软件研发的工具;
  3. 用面向对象的思想来进行具体的代码实现;

说明

原创文章链接:从零开始学习数据结构-->入门篇