逻辑结构
数据集合中各数据元素之间所固有的逻辑关系
数据的逻辑结构有以下两大类:
线性结构:有且仅有一个开始结点和一个终端结点,且所有结点都最多只有一个直接前驱和一个直接后继。
线性表是一个典型的线性结构。栈、队列、串、数组等都是线性结构。
非线性结构:在该类结构中至少存在一个数据元素,它具有两个或者两个以上的前驱或后继。
如树和二叉树集合结构和多维数组、广义表、图、堆等数据结构都是非线性结构。
-
线性结构
栈(Stack)
只允许在表尾进行插入或删除操作的线性表。
原则:先进后出,后进先出。队列(Queue)
只允许在表的一端进行插入,而在另一端进行删除的运算受限的线性表。
原则:先进先出,后进后出。 -
非线性结构
二叉树
- 满二叉树是指除最后一层外,每一层上的所有结点有两个子结点,则k层上有2k-1个结点深度为m的满二叉树有2m-1个结点。
- 完全二叉树是指除最后一层外,每一层上的结点数均达到最大值,在最后一层上只缺少右边的若干结点。
基本性质:
- 在二叉树的第k层上,最多有2k-1(k≥1)个结点;
- 深度为m的二叉树最多有2m-1个结点;
- 度为0的结点(即叶子结点)总是比度为2的结点多一个;
- 具有n个结点的二叉树,其深度至少为[log2n]+1,其中[log2n]表示取log2n的整数部分;
- 具有n个结点的完全二叉树的深度为[log2n]+1;
- 设完全二叉树共有n个结点。如果从根结点开始,按层序(每一层从左到右)用自然数1,2,….n给结点进行编号(k=1,2….n),有以下结论:
①若k=1,则该结点为根结点,它没有父结点;若k>1,则该结点的父结点编号为int(k/2);
②若2k≤n,则编号为k的结点的左子结点编号为2k;否则该结点无左子结点(也无右子结点);
③若2k+1≤n,则编号为k的结点的右子结点编号为2k+1;否则该结点无右子结点。
二叉树的遍历:
- 前序遍历,首先访问根结点,然后遍历左子树,最后遍历右子树;
- 中序遍历,首先遍历左子树,然后访问根结点,最后遍历右子树;
- 后序遍历,首先遍历左子树,然后访问遍历右子树,最后访问根结点。
关于遍历顺序,我自己记忆的方法是,名称中的前中后代表根结点的访问位置,而子树按照先左后右,即:
前,表示访问根节点在前,因此顺序是根、左、右;
中,表示访问根节点在中,因此顺序是左、根、右;
后,表示访问根节点在后,因此顺序是左、右、根;
存储结构
在对数据进行处理时,各数据元素在计算机中的存储关系
-
顺序存储
顺序存储方法是把逻辑上相邻的元素存储在物理位置相邻的存储单元中,由此得到的存储表示称为顺序存储结构。
顺序存储结构是一种最基本的存储表示方法,通常借助于程序设计语言中的数组来实现。 -
链式存储
链式存储方法对逻辑上相邻的元素不要求其物理位置相邻,元素间的逻辑关系通过附设的指针字段来表示,由此得到的存储表示称为链式存储结构。
链式存储结构通常借助于程序设计语言中的指针类型来实现。
基本运算
算法
时间复杂度:指执行算法所需要的计算工作量
空间复杂度:指执行这个算法所需要的内存空间
-
查找
顺序查找
时间复杂度: O(n)
二分查找
时间复杂度: O(log2n)
插值查找
插值查找基于二分查找,将查找点的选择改进为自适应选择(让mid值的变化更靠近关键字key),提高查找效率,属于有序查找。
时间复杂度:O(log2(log2n))
斐波那契查找
斐波那契查找也是基于二分查找,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率,属于有序查找算法。
要求:开始表中记录的个数为某个斐波那契数小1,及n=F(k)-1;
时间复杂度: O(log2n)树表查找
分块查找
哈希查找
-
排序
排序这块我主要是通过阅读一下这篇文章来理解每种排序算法的具体运作,以及时间复杂度如何计算的,文章中用到一些图片及动图来说明,感觉帮助挺大的。很棒~ 此处就直接放上传送门吧:几种常见的排序方法