1、数据结构论述
数据元素:即一条记录
数据项:一条记录中的某些属性
数据对象:数据元素的集合
数据结构:相互之间存在一种或者多种特定关系的数据元素的集合
逻辑结构:集合结构、线性结构、属性结构、图形结构
物理结构:数据的逻辑结构在计算机中的存储形式
1、顺序存储
2、链式存储
注意:逻辑结构是面向问题的;物理结构是面向计算机的
2、算法和数据结构的关系
算法是利用数据结构解决问题的方式
算法的特性:输入、输出、又穷性、确定性、可行性
大O标示法:
用数常量1取代运行时间的所有加法常
在修改后的运行次数函数中,只保留最高阶
如果最高阶项存的不是1,则去除与这个项相乘的常数
3、静态链表:用数组描述的链表叫做静态链表
线性表有2中存储方式:顺序存储和链式存储
4、栈是限定仅在表尾进行插入和删除的线性表
栈按数据存储方式:顺序栈和链栈
允许插入和删除的是栈顶,另一端是栈底
栈又称后进先出
栈的插入操作:入栈、压栈
栈的删除操作:出栈、弹栈
逆波兰:有叫后缀表达式
执行的规则:从左到右遍历表达式的每个数字和符号,遇到数字就进栈。遇到符号,就将处于栈顶的2个数字出栈,进行计算,并将计算结果入栈,一直到最终获取结果。
中缀表达式转后缀表达式规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号,则判断其栈顶符号的优先级,是右括号或优先级低于栈顶符号(乘除优先于加减),则栈顶元素依次出栈输出,并将当前符号进栈,一直到最终输出后缀表达式为止;
5、队列是允许在一端进行插入操作,而另一端进行删除操作的线性表 FIFO先进先出
顺序队列缺点:当一个元素被删除后,整个队列所有的元素都要向前移动,保证队列的头部下表是0
所以出现了循环队列
引入2个指针:front 和 rear ;front指向队列的头元素,rear指向队列的尾元素的下个位置;front = rear时队列中没有元素;
出队时,front指针向后移动
循环队列:我们把头尾相连的顺序存储结构成为循环队列;
当队列元素为null时和对列元素满时,front和rear位于同一个位置;如何判断是null还是满了呢?
1)front == rear 和flag作为判断依据
2)null时 front == rear ; 当队列满时,数组中保留一个空闲单元;
2情况的判断依据 (rear + 1)%queueSize == front
队列长度的通用计算公式:(rear-front + queueSize)%queueSize
树的度:标示子节点的个数
数的存储结构:【顺序存储,链式存储】
顺序存储:一般是完全二叉树
二叉链表:data、lchild、rclild
1、双亲标示法 data parent
2、孩子标识法 child next
3、孩子兄弟表示法
二叉树:是n个结点的有限集合,该集合或者空集,或者由一个根结点和两颗互不相交的,分别称为根结点的左子树和右子树的二叉树组成
分类:
斜树
满二叉树:叶子节点是满的
完全二叉树:编号连续的
性质:
1、在二叉树的第i层,至多有2的i-1次方个节点(i>=1)
2、深度为k的二叉树,至多有2的k次方减1个结点
3、对任何一颗二叉树T,如果其终端的结点数n0,度为2的结点数为n2,则 n0= n2 + 1
4、具有n个节点的完全二叉树 ,深度为log2(n)+ 1
5、如果对一颗有n个结点的完全二叉树,其深度为log2 (n) + 1;对任一结点i (i<=n),
5.1、有i = 1 则 结点为根结点,i>=1 则有双亲结点为[i/2]
5.2、如果2i > n,则i无左结点,否则其左孩子 是结点2i;如果2i + 1 >n,则结点i无右孩子,否则其右孩子是结点2i+1
二叉树的遍历
前序遍历:递归的代码:data -> lchild -> rclild
中序遍历:递归的代码:lchild -> data -> rclild
后序遍历:递归的代码:lchild -> rclild -> data
层序遍历:按序号顺序遍历
树、二叉树、森林的转换
1、树 -> 二叉树
步骤1:加线:所有兄弟节点之间加一条连线
步骤2:对树中每个结点,只保留它与第一个孩子结点的连线;删除它与其他孩子结点之间的连线
步骤3:层次调整:以树的根结点为轴心,将整棵树顺时针旋转一定的角度,使之结构层次分明,注意每个孩子是二叉树结点的左结点;兄弟换过来的孩子是结点的右孩子;
2、森林 —> 二叉树
1、每棵树转成二叉树
2、第一颗二叉树不懂,从第二颗树开始,一次把后一颗二叉树根结点作为前一个树根结点的右孩子,用线连接起来,当所有的二叉树连接起来后,得到了森林转二叉树;
3、二叉树 -->树
1、左孩子n个右孩子结点连接起来;
2、删除原二叉树中所有及诶大与右孩子结点连线
4、二叉树 -> 森林
1、断右孩子的连线
//////////////////////////////////////////////////////////////////////////////////////////
规律:森林的前序遍历和后序遍历和二叉树的前序遍历和后续遍历一致
赫夫曼树:
路径长度:从书中结点到另一个结点之间的分支构成2个结点之间的路径,路径上的分支数目成为路径的长度
树的长度:根结点到每个结点的长度
如何构建自己的二叉树方法:
1、先把有权值的叶子结点按照从小到大的顺序排列成一个有序序列,即:A5,E10,B15,D30,C40
2、取头两个最小权值的结点作为一个新结点N1的两个子结点,注意相对较小的是左孩子,这里就是A为N1的左孩子,E为N1的右孩子。新结点的权值为两个叶子权值的和5+10=15
3、将N1替换A与E,插入有序序列中,保持从小到大排列。即N115,B15,D30,C40
4、重复步骤2,将N1与B作为新的结点N2的两个子结点
5、将N2替换N1与B,插入有序序列中,保持从小到大排列。即:N230,D30,C40
6、重复步骤2。将N2与D作为一个新结点N3…
赫夫曼编码:
比如要传输一段字符串:BADCADFEED
用二进制传送:001000011010000011101100100011(30个字符)
分析:这段字符串中只有ABCDEF,假设出现的频率为A27,B8,C15,D15,E30,F5;根据赫尔曼树可以构建自己的二叉树;最后把权值左分支改为0,有分支改为1;
新编码的二进制为:1001010010101001000111100(25个字符)
也就是说空间被压缩了,随着字符的增加,压缩程度更加明显。
接收方收到二进制,没发进行解码;需要赫尔曼树才能解码