数据结构

数据结构(一) — 绪论

你。 提交于 2020-03-30 08:36:39
一 、说明 又到了一年的跳槽季,不会点数据结构与算法的知识怎么行呢?本系列文章参考(剽窃— _—)《大话数据结构》,希望大家共勉。 文章底部分享《大话数据结构》下载连接。 二、基本概念和术语 数据 数据 : 是描述客观事物的符号,是计算机中可以操作的对象,是能被计算机识别,并输入给计算机处理的符号集 。 数据不仅仅包括整型、实型等数值类型,还包括字符及声音、图像、视频等非数值类型。 我们这里说的数据,其实就是符号,而且这些符号必须具备两个前提: • 可以输入到计算机中。 • 能被计算机程序处理 数据元素 数据元素 :是组成数据的、有一定意义的基本单位,在计算机中通常作为整体处理。 也被称为记录。 比如,牛、马、羊、鸡、猪、 狗等动物就是禽类的数据元素。 数据项 数据项:一个数据元素可以由若干个数据项组成。 比如人这样的数据元素,可以有眼、耳、鼻、嘴、 手、脚这些数据项,也可以有 姓名、年龄、性别、出生地址、联系电话等数据项,具体有哪些数据项,要视你做的系统来决定。 数据项是数据不可分割的最小单位 。在数据结构中,我们把数据项定义为最小单位,是有助于我们更好地解决问题。所以,记住了,数据项是数据的最小单位。但真正讨论问题时,数据元素才是数据结构中建立数据模型的着眼点。就像我们讨论一部电影时,是讨论这部电影角色这样的"数据元素",而不是针对这个角色的姓名或者年龄这样的"数据项

数据结构之堆栈

馋奶兔 提交于 2020-03-29 19:04:33
谈起堆栈,我想起兄弟。中国的汉语真是有意思,兄弟说的是弟,同理,堆栈,强调的是 栈 。栈是一种 受限的线性表 。我把数据结构的知识回顾下。 数据结构是数据之间的关系 。关系是普遍存在的。是不是有点哲学的味道。那么数据到底都有些什么关系呢?我们去银行办理业务,去坐车都需要排队,新生入学站成一排军训,如果我们把人看作数据,那么此时的人和人的位置关系,便是线性的。除了 线性结构 ,还有什么结构呢?四世同堂的老人,他们一家人的血缘关系,如同一棵树。这便是 树型结构 。还有一种网状的结构,称为 图 ,如城市的交通网。字典属于什么数据结构?它不是树,不是图,那它属于线性结构吗? 字典 显然是个 集合 ,如果字典的key是线性关系,例如从1开始的编号,或者是a-z的字母,那么它能称得上线性关系吗?线性表是一种有限序列的集合。它是有顺序的。字典的数据项完全没有任何逻辑,它只与key有关系。 说了这么多,总结一下:数据之间的关系分为两种,逻辑关系和非逻辑关系如图所示: 今天我要说的栈是一种物理结构,它存储了一组线性元素,这组元素在 操作 上有 后进先出 的特性。因此可以看出, 数据结构不仅研究数据之间的关系,以及存储,而且包括数据的操作。 结构决定功能 ,正是有了栈这样的存储结构,因此,元素的操作上才有自己的特性。 接下来,我们看一个栈具体应用的例子:有一组有序数字

数据结构——树与二叉树

和自甴很熟 提交于 2020-03-29 19:01:14
目录 导言 什么是树 树结构定义 树的结点 结点分类 结点的联系 结点的层次 有序树 森林 相比线性结构 树的存储结构 双亲表示法 结构体定义 描述法举例 孩子表示法 描述法举例 结构体定义 孩子兄弟表示法 描述法举例 二叉树 二叉树的定义 特殊的二叉树 斜树 满二叉树 完全二叉树 二叉树的性质 二叉树的存储结构 顺序存储 链式存储 结构体定义 二叉树的基本操作 二叉树的遍历 从斐波那契数列说起 遍历算法 建立二叉树 拓展二叉树 建树算法 复制二叉树 获取二叉树的深度 统计二叉树的结点数 线索二叉树 描述前驱与后继 线索二叉树结点结构体定义 线索化 遍历线索二叉树 参考资料 导言 轩辕剑是一个经典的中文角色扮演游戏,通过对历史内容的考究,与精彩感人的剧情结合,使得这个系列被公认为华人世界的两大经典角色扮演游戏系列之一。我最为喜欢的两部是《轩辕剑叁:云和山的彼端》和《轩辕剑叁外传:天之痕》,剧情感人精彩、别有深意,2D的场景细致美观、独具特色……当然,我这次仍然不是来给你推荐游戏的,而是想对其中一个场景做点文章。 “建木”是上古先民崇拜的一种圣树,传说建木是沟通天地人神的桥梁,在《轩辕剑叁外传:天之痕》中的仙山岛,利用水墨画的风格进行了描绘,是我最喜欢的游戏场景之一。其中就有对“海中建木”的描绘。“海中建木”无疑是一颗巨大的树,这棵树也肯定是由无数的根、枝、叶组成的,如果我们把

基于锁的并发数据结构

笑着哭i 提交于 2020-03-29 04:04:55
1. 使用细粒度锁和条件变量的线程安全队列 可以使用细粒度的锁来减小队列的临界区,这里使用了一个dummy node用来进一步减小锁的临界区。若要判断队列是否为空,只需要执行下述判断: head.get() == get_tail() 请注意,因为在进行push的时候需要修改tail,所以对tail的访问和修改都需要进行加锁。这里使用get_tail来封装这个操作,将锁的粒度减小到最低。 // lock tail mutex and return tail node node *get_tail() { std::lock_guard<std::mutex> tail_lock(tail_mutex); return tail; } 对push的操作只涉及到修改tail节点,所以只需要对tail节点进行加锁。加锁完成之后就可以修改tail使其指向新的tail节点。 void push(T new_value) { std::shared_ptr<T> new_data(std::make_shared<T>(std::move(new_value))); std::unique_ptr<node> p(new node); { std::lock_guard<std::mutex> tail_lock(tail_mutex); tail->data = new_data; node

并发编程(6)基于锁的并发数据结构设计

…衆ロ難τιáo~ 提交于 2020-03-29 04:03:42
主要内容: 并发数据结构设计的意义 指导如何设计 实现为并发设计的数据结构   如果一种数据结构可以被多个线程所访问,其要不就是绝对不变的(其值不会发生变化, 并且不需同步),要不程序就要对数据结构进行正确的设计,以确保其能在多线程环境下能够 (正确的)同步。一种选择是使用独立的互斥量,其可以锁住需要保护的数据, 另一种选择是设计一种能够并发访问的数据结构。第一种使用互斥量,在同一时间只有一个线程可以访问数据,实际是一种串行的序列化访问。显示的组织了多线程对数据结构的并发访问。 所以,缩小保护区域,减少序列化访问,就能提高并发。 允许线程并发读取的数据结构并不少见,而对数据结构的修改,必须是单线程独立访问。 所以不可能完全实现并发,只能让序列化访问最小化。 一、基于锁的并发数据结构 基于锁的并发数据结构设计,需要确保访问线程持有锁的时间最短。都是在保证数据结构是线程安全的前提下。在设计数据结构,考虑以下问题: 锁的范围中的操作,是否允许在所外执行? 数据结构中不同的区域是否能被不同的互斥量所保护? 所有操作都需要同级互斥量保护吗? 能否对数据结构进行简单的修改,以增加并发访问的概率,且不影响操作语义? 1、使用锁实现一个线程安全的栈 1 #include <exception> 2 struct empty_stack: std::exception 3 { 4   const

数据结构,算法及线性表总结

て烟熏妆下的殇ゞ 提交于 2020-03-28 20:44:20
1.思维导图 2.重要概念笔记 1.数据结构 1.数据结构定义 -我们如何把现实中大量而复杂的问题以特定的数据类型和特定的存储结构保存到主存储器(内存)中,以及在此基础上为实现某个功能(比如查找某个元素,删除某个元素,对元素进行排序等)而执行的相应操作,这个相应的操作也叫算法。 2.算法 -衡量算法的标准: -时间复杂度:程序大概要执行的次数,而非执行的时间 -空间复杂度:程序执行过程中大概所占用的最大内存空间 -难易程度:用易懂,避免过于复杂 -健壮性 3.连续存储【数组】 -什么叫数组:元素类型相同,大小相等 -数组的优缺点 --优点:存取速度很快 --缺点:插入删除元素很慢 4.离散结构【链表】 -定义:n个节点离散分配,彼此通过指针相连,每个节点只有一个前驱节点同时每个节点只有一个后续节点,首节点没有前驱节点,尾节点没有后续节点 -专业术语 --首节点:存放第一个有效数据的节点 --尾节点:存放最后一个有效数据的节点 --头结点:位于首节点之前的一个节点,头结点并不存放有效的数据,加头结点的目的主要是为了方便对链表的操作 --头指针:指向头结点的指针变量 --尾指针:指向尾节点的指针变量 -确定一个链表需要几个参数:只需要一个头指针参数,因为我们通过头指针可以推算出链表的其他所有信息 -分类: --单链表:每一个节点只有一个指针域 --双链表:每一个节点有两个指针域 -

数据结构、算法及线性表总结

℡╲_俬逩灬. 提交于 2020-03-28 19:23:14
··· //初始化表 void InitList(SqList *&L) { L=new SqList;//为线性表分配空间 L->length=0; } //销毁线性表 void DestoryList(SqList* &L) { delete L;//释放L指向的内存空间 } //获取元素 bool GetElem(SqList *L,int i,ElemType &e) { if(i<1||i>L->length) return false; e=L->data[i-1]; return true; } //插入元素 bool ListInsert(SqList *&L,int i,ElemType e) { if(i<1||i>L->length) return false; i--; for(int j=L->length;j>i;j--) L->data[j] = L->data[j-1]; L->data[i]=e; L->length++; return true; } //删除元素 bool LiseDelete(SqList *&L,int i,ElemType &e) { if(i<1||i>L->length) return false; i--; e=L->datd[i]; for(int j=i;j<L->length-1;j++) L->data[j]

数据结构-概念总结

大城市里の小女人 提交于 2020-03-28 19:14:48
数据结构概念总结 Data Structures + Algorithms = Programs 一.数据结构 1.基本概念: 数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合 2.数据结构的逻辑结构分为四种: 集合结构,线性结构,树形结构,图结构。 3.数据结构的物理结构分为两种: 顺序存储结构和链式存储结构. 4.学习数据结构的用途: 数据结构在计算机专业课程体系中起到承上启下的作业,熟练使用数据结构可以使程序运行的更快更流畅 思维导图: 二.算法 1.定义: 对特定问题求解步骤的一种描述,它是指令的特定序列,每一条指令表示一个或多个操作 2.特性: 有穷性,确定性,可行性,输入,输出。 3.算法的描述: 自然语言,流程图,程序设计语言,伪代码。 4.算法分析: (1)算法设计的目标: 正确性,可使用性,可读性,健壮性,时间效率高与存储量低 (2)两种衡量算法效率的方法: 事后统计法(把程序跑一遍): 必须执行程序,且存在其他因素掩盖算法本质 事前估计法(撇开软硬件相关因素,仅考虑算法本身效率): 算法执行时间=基本运算时间*运算次数 基本运算:被视为算术运算的一般是最深层循环内语句 (3)算法效率分析: 算法的执行时间可由其基本运算的执行次数来计算 时间复杂度:记号"O",表示随问题规模n增大,算法执行时间的增长率和f(n

数据结构、算法及线性表总结

独自空忆成欢 提交于 2020-03-28 19:09:16
数据结构、算法及线性表总结 本学期学习了数据结构这门课,为了能够理清学习历程,在此记录学习到的知识,以供参考。 一、本课程的思维导图(持续更新) 二、重要概念的笔记及个人解析 <font color=>第一章:绪论 1)数据结构的定义:数据结构是指所有数据元素以及数据元素之间的关系,可以看作是相互之间存在着某种特定关系的数据元素的集合 (带结构的数据的集合) 2)逻辑结构的定义:逻辑结构是从数据元素的逻辑关系上描述数据的,它与数据的存储无关,是从具体问题中抽象出来的数学模型。 (用来描述数据之间有怎样的关系,或哪种类型的关系) 3)逻辑结构的类型:逻辑结构是多样复杂的,现阶段我们接触到的有 集合 、 线性结构 、 树形结构 以及 图形结构 。(目前学习到线性结构) 4)存储结构的定义:存储结构是数据元素及其关系在计算机存储器中的存储表示也称为物理结构,常用的有 顺序存储 、 链式存储 、 索引存储 和 哈希存储 四中存储结构。 5)顺序存储结构:用该结构存储数据元素,所有数据元素在存储器中占有一整块存储空间, 可将逻辑结构直接映射到存储结构 。(优点:存储效率高,没有额外占用的空间,还可以实现对元素的随机存取。缺点:不便于数据修改,一个元素的变动就可能使其他一系列元素也要进行移动) 6)链式存储结构:每一个数据元素占用的只是一个内存节点,每个节点单独分配,地址也不一定连续

图解数据结构(3)——队

谁说胖子不能爱 提交于 2020-03-28 18:35:06
五、队(Queue) 前一篇讲了栈(Stack),队和栈其实只有一个差别,栈是先进后出,队是先进先出,如图: 从图中可以看出,队有两个常用的方法,Enqueue和Dequeue,顾名思义,就是进队和出队了。队和栈一样,既可以用数组实现,也可以用链表实现,我还是偏向于用数组,我的实现示意图如下: 队有啥用呢?一个最常用的用途就是“buffer”,即缓冲区,比如有一批从网络来的数据,处理需要挺长的时间,而数据抵达的间隔并不均匀,有时快,有时慢,先来的先处理,后来的后处理,于是你创建了一个队,用来缓存这些数据,出队一笔,处理一笔,直到队列为空。当然队的作用远不止于此,下面的例子也是一个很经典的例子,希望读者能举一反三。 例子:使用队对树进行广度优先遍历。 广度优先区别于深度优先,即优先遍历最靠近根节点的各个节点: 我们的算法是: 1,根节点入队 2,出队一个节点,算一次遍历,直到队列为空 3,将刚出队的节点的子节点入队 4,转到2 队列的状况如下图: 树的遍历一般习惯使用递归,理论上所有的递归都可以转变为迭代,如何实现这个转变?队就是其中一种有效的办法,OK,下面我给出上述例题的代码以及注释。 //Not grace code but enough for demo. ^_^ #include "stdio.h" // The Node /////////////////////////