数据结构知识点系列一
1、预备知识
逻辑结构:集合结构、线性结构、树形结构、图形结构
物理结构:顺序存储结构和链式存储结构
算法的特性:输出、输出、有穷、确定性、可行性
时间复杂度:大O阶: O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)
2、线性表
线性表:零个或多个数据元素组成的有序序列。有顺序存储结构和链式存储结构(结点=数据域+指针域)。
3、栈和队列
栈:
限定在表尾(栈顶)进行插入和删除的线性表。后进先出
进栈: s→top++,s→data[s→top]=e
出栈: ∗e=s→data[s→top],s→top−−
栈的应用:四则运算表达式求值
中缀—>后缀:栈用来进出运算符,从左到右遍历中缀表达式,若是数字,就输出;若是符号,则判断其与栈顶元素优先级,若是右括号或优先级低于栈顶元素,则栈顶元素出栈,当前符号进栈。
后缀运算:栈用来进出数字,遇到数字进栈,遇到运算符,后两个数字出栈做运算,运算结果进栈。
队列:
定义:只允许在一端(队尾)进行插入,另一端(队头)进行删除的线性表。先进先出
循环队列:解决“假溢出”,仍存在真溢出(空间溢出)。front对头,rear队尾元素的下一个位置。初始状态:rear=front。空队列:rear==front。队满:(rear+1)%Size\==front。队列长度:(rear-front+Size)%Size。
4、串
定义:由零个或多个字符组成的有限序列。
模式匹配:
子串(长度为m)查找(主串长度为n):最好时间复杂度 O(n+m) ,最坏时间复杂度 O(n−m+1)∗m 。
//朴素的模式匹配算法
int Index(String S,String T,int pos){
int i = pos;
int j = 0;
while (i<S.size() && j<T.size()){
if (S[i]==T[j]){
++i;++j;
}else{
i = i-j+2;
j = 0;
}
}
if (j>=T.size()) return i-S.size();
return 0;
}
KMP模式匹配算法:主串索引i不可以变小,子串索引j的变化。
//KMP模式匹配算法
//返回计算子串T的next数组,即子串索引j的数组
void get_next(String T,int* next){
int i,j;
i = 0;j = -1;
next[0] = 0;
while (i<T.size()){
if (j==-1 || T[i]==t{j}){
++i;++j;
}else{
j = next[j];
}
}
}
//O(n+m)
void Index_KMP(String S,String T,int pos){
int i = pos;
int j = 0;
int next[255];
get_next(T,next);
while (i<S.size() && j<T.size()){
if (S[i]==T[j]){
++i;++j;
}else{
j = next[j];
}
}
if (j>=T.size()) return i-S.size();
return 0;
}
//改进KMP
void get_nextval(String T,int* nextval){
int i,j;
i = 0;j = -1;
nextval[0] = 0;
while (i<T.size()){
if (j==-1 || T[i]==t{j}){
++i;++j;
if (T[i]!=T[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
}else{
j = nextval[j];
}
}
}
5、树
度:结点拥有的子树的个数(度为0称为叶结点),树的度是各结点度的最大值。
深度:树中结点的最大层次。
树的存储结构:双亲表示法、孩子表示法、孩子兄弟表示法。
二叉树:
性质:在二叉树的第i层至多有 2i−1 个结点;深度为k的二叉树至多有 2k−1 个结点;叶结点数为 n0 ,度为2的结点数为 n2 ,则: n0=n2=1 具有n个结点的完全二叉树深度为 ⌊log2n⌋+1 ;对一颗有n个结点的二叉树按层序编号,对任意编号为i的结点:若i=1,则结点为根;若i>1,其双亲编号为 ⌊i2⌋ ;若2i>n,该结点无左孩子,否则其左孩子编号为2i;若2i+1>n,该结点无右孩子,否则其右孩子编号为2i+1。
遍历二叉树:
前序遍历:先访问根结点,再前序遍历左子树,再前序遍历右子树。
中序遍历:先中序遍历根结点的左子树,然后访问根结点,最后中序遍历根结点的右子树。
后序遍历:先后序遍历根结点的左子树,然后后序遍历根结点的右子树,最后访问根结点。
层序遍历:按层序编号依次访问结点。
已知前、中序遍历序列或后、中序遍历序列可以唯一确定一颗二叉树。
赫夫曼树:
路经长度:从树中一个结点到另一个结点的分支构成路径,路径上的分支数目(树的路径长度为结点路径长度之和)。
带权路经长度(WDL)=路径长度*权重。
赫夫曼树是带权路经长度最小的二叉树。
构造赫夫曼树:构造结点权值从小到大排序的结点序列—>取序列中前两个结点作为新结点的左右孩子(权重小的为左孩子),将新结点(权重为两个结点的权重和)加入序列中,重复上述过程,直到取完所有结点。
赫夫曼编码:根据需要编码的字符集及其频率构造赫夫曼树,左分支为0,右分支为1,从根结点到叶结点的路径序列为对应字符的编码。