数据 : 能输入计算机且能被计算机识别
数据对象
数据元素
数据项
数据结构的研究对象是 : 数据元素
逻辑结构-数据对象中数据元素之间的相互关系
集合结构:元素之间无关系
线性结构:元素之间是一对一的关系
树形结构:元素之间是一对多的关系
图形结构:元素之间是多对多的关系
物理结构-数据的逻辑结构在计算机中的存储形式
顺序存储结构:用一块连续的内存存储数据元素。数据间逻辑关系与物理关系是一致的。
链式存储结构:用连续的或者不连续的内存存储数据,数据间的关系用指针来表示。
算法 : 解决问题的步骤,在计算机中的表现就是指令序列
**************************************************************************************************************************************************************
线性表:零个或多个数据元素的有限序列。 强调: 元素有限且有序
存储结构: 顺序存储结构-用一段地址连续的存储单元一次存储线性表的数据元素
链式存储结构-n个结点链接成一个链表
结点的指针域数量均为1且指向后继结点的链表,叫做单链表
用数组描述的链表,叫做静态链表。用在一些无法实现指针概念的编程语言中,比如:Basic、Fortran
将单链表的终端结点的指针域由空指针改为指向头结点,使单链表形成一个环。这种头尾相接的单链表链表称为单循环链表
在单链表的每个结点中,再设置一个指针指向其前驱结点,这样改造后的单链表叫做双向链表
栈:限定仅在一端进行插入、删除操作的线性表
顺序栈、链栈
队列:限定仅在一端进行插入操作、在另一端进行删除操作的线性表
将队列的头尾相相接的顺存储结构称为循环队列
队列的链式存储结构,叫做链队列
串:
1>由来:当在计算机上做非数值处理的工作越来越多的时候,自然而然的就引进了对字符串的处理。相应的就出现了字符编码,例如 ASCII、Unicode 等
2>定义:由有限个(零个或者多个)字符组成的序列,又叫做字符串
3>子串:串中任意个数的相邻的字符组成的子序列
4>串的比较:组成串的 字符的编码 之间的比较。 字符的编码:字符在对应字符集中的序号
串的模式匹配:统计主串中子串出现的次数、或者定位子串(T)的位置,类似这种子串定位的操作通常称做串的模式匹配
1>朴素的模式匹配算法:对主串的每个字符作为子串的开头,与要匹配的子串进行匹配。主串做大循环,每个字符开头做
T长度的小循环,直到匹配成功或全部遍历完成为止。
朴素的模式匹配算法流程:
假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置,则有:
如果当前字符匹配成功(即S[i] == P[j]),则i++,j++,继续匹配下一个字符;
如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0。相当于每次匹配失败时,i 回溯,j 被置为0。
2>KMP模式匹配算法:任务 --- 用于在一个文本串S内查找一个模式串 P 的出现位置
思想 --- 在字符串O中寻找f,当匹配到位置i时两个字符串不相等,这时我们需要将字符串f向前移动。
常规方法是每次向前移动一位,但是它没有考虑前i-1位已经比较过这个事实,所以效率不高。
如果我们提前计算某些信息,就有可能一次前移多位。
KMP算法流程:
假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置
如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++,继续匹配下一个字符;
如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]。此举意味着失配时,模式串P相对于文本串S向右移动了j - next [j] 位。
next数组的简单笔记:
叫做前缀数组,也有的叫next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,
当然它描述的也是子串的对称程度(不是中心对称,而是中心字符块对称,比如不是abccba,而是abcabc这种对称),程度越高,值越大,当然之前可能出现再匹配的机会就更大。
当模式串中的某个字符跟文本串中的某个字符匹配失配时,模式串下一步应该跳到哪个位置。如模式串中在j 处的字符跟文本串在i 处的字符匹配失配时,
下一步用next [j] 处的字符继续跟文本串i 处的字符匹配,相当于模式串向右移动 j - next[j] 位
next 数组各值的含义 --- 当前位置匹配失败的时候,下标应该改变到的位置。
代表当前字符之前的字符串中,有多大长度的相同前缀后缀。
例如如果next [j] = k,代表j 之前的字符串中有最大长度为 k 相同前缀后缀
注意 : KMP中的 最大长度表 与 Next数组 的区别
树:n(n>=0)个结点的有限集
n = 0 ,空树
n != 0 :
有且仅有一个称为跟的结点
n>1时,除跟结点之外的其他结点又可以组成m(m>0)个互不相交的有限集,
其中每一个集合又是一颗树,并且称为跟的子树
树的基本术语: 1>结点的度 --- 结点拥有的子树的数目
2>叶子 --- 度为零的结点
3>分支结点 --- 度不为零的结点
4>树的度 --- 树中结点的最大的度
5>层次 --- 跟结点的层次为1,其余结点的层次等于该结点双亲结点的层次加1
6>树的高度 --- 树中结点最大的层次
7>有序树 --- 如果树中结点的各子树之间的次序是重要的, 不可以交换位置
8>无序树 --- 如果树中结点的各子树之间的次序是不重要的,可以交换位置
9>森林 --- 0个或多个不相交的树组成。对森林加上一个根,森林即成为树;删去根,树即成为森林。
满二叉树 --- 深度为 h ,并且有 (2^h) - 1 个结点的二叉树
完全二叉树 --- 对一棵具有n个结点的二叉树按次序编号,如果编号为i(1<= i <= n)的结点与同样深度的满二叉树中的编号为i的结点在二叉树中的位置相同,
则这课二叉树为完全二叉树
满二叉树一定是完全二叉树,反之不然。
二叉查找树 --- 又称二叉搜索树。如果x是二叉查找树中的一个结点,其左子树上的记录都小于等于该结点的记录,其右子树上的记录都大于等于该结点的记录。
二叉树的存储结构:
1>顺序存储 --- 用一位数组来存储二叉树中的结点,但是结点的地址(即数组的下标)要能体现结点之间的逻辑结构
对完全二叉树完全可以用顺序存储结构来存储,但是对于一般的二叉树呢?
当然也可以,只需要将结点按照完全二叉树编号,没有结点的位置用null来代替即可。
也就是说,一个深度为n的一般二叉树,需要分配 (2^n) - 1 个空间来满足其顺序存储结构。
考虑一个极端情况,这课一般二叉树只有右子树,怎么样?是不是会造成很多空间的浪费
因此,顺序存储结构一般只使用与完全二叉树。
2>l链式存储结构 --- 二叉链表
二叉树的遍历次序:
1>先序遍历
2>中序遍历
3>后序遍历
4>层序遍历
为什么要有这么多的遍历方式?因为计算机只会处理线性序列,这些不同的遍历方式,实际上就是把树中的结点变成了某种意义上的线性序列
线索二叉树 --- 按照某种遍历方式遍历二叉树的过程中,将结点中的空指针指向结点的前驱或后继(左空指针指向前驱、右空指针指向后继) 的过程,叫做二叉树的线索化,这些空指针有了一个新的名字,叫做线索。
加上线索的二叉链表叫做线索链表,相应的二叉树就叫做线索二叉树。
*********************************************************************************************************************************************************************
查找:
散列表(哈希表)查找
散列技术---在记录的存储位置和它的关键字之间建立一个对应关系f,使得对于每个关键字key对应一个存储位置f(key).
对应关系f叫做散列函数(哈希函数)
采用散列技术将记录存储在一块地址连续的存储空间中,这块地址连续的存储空间叫做散列表(哈希表)。
关键字对应的存储位置叫做散列地址(哈希地址)
********************************************************************************************************************************************************************
排序:
1、稳定排序和不稳定排序
相等的两个元素在排序前后的相对位置不发生变化称之为稳定排序,否则,是不稳定排序。
2、内排序和外排序
排序的过程中,待排序的记录全部在内存中称之为内排序,否则称之为外排序。
而数据结构中涉及的排序基本都指内排序。
3、影响内排序性能的主要因素:
时间性能、辅助空间、算法本身的复杂度
4、主要分类:
插入排序、交换排序、选择排序、归并排序
5、按照算法的复杂度分为两大类:
简单算法---冒泡排序、简单选择排序、直接插入排序
改进算法---希尔排序、堆排序、归并排序、快速排序
冒泡排序-两两比较相邻记录的关键字,反序则交换,直到没有反序的记录为止
简单选择排序-每次从 n-i+1(i= 1,2,3, ...,n-1) 个记录中选择关键字最小的记录做为有序序列的第 i 个记录
直接插入排序-将一个记录插入已经排好序的有序表中,得到一个新的、记录数加1的有序表