数据结构小点 二号
链表:非连续的地址(数据域+指针域)
随机访问一般是下标
时间复杂度计算:1.只要没有循环等复杂结构,那就是O(1)
2.单一for循环O(n)  		3.嵌套循环:O(n^...)		  4.斐波那契数列的递归:O(2^n)
5.while循环里i每次乘2,越来越接近n 😮(logn)		6.上述结合
空间复杂度:1.已分配的临时空间不随变量值大小变化而变化O(1)
2.new一个数组int[n],O(n)
线性表的存储方式又顺序存储和链式存储,查找的时间复杂度是O(1)
树形结构是非线性结构,是由分支关系定义的层次结构
节点的度(叉):节点下一层有几个节点
节点深度:在第几层
节点高度:当前节点到其最远叶节点的长度
树的遍历方式:层次遍历和三大遍历
层次遍历是先上到下,先左后右(相当于每一层从左到右),实现方法用队列:先将根节点入队,进入循环---出队一个元素以及其子节点入队(没有子节点就继续出队一个元素)
遍历递归方案void PreOrder(BiTree TT){
if(TT == NULL) return;//先序放第一句,中序第二,后序第三句
visit(TT);PreOrder(TT->lchild);PreOrder(TT->rchild);
}
求二叉树高度:int TreeDepth(BiTree TT){ if(TT == NULL) return 0;
int ll = TreeDepth(TT->lchild);
int rr = TreeDepth(TT->rchild);
return ll<rr ? ll+1 : rr+1;
}
非递归方案(栈实现):1.从根节点出发,沿左节点依次入栈,直到左节点为空;
2.栈顶元素出栈
3.如果出栈元素有右节点,把右节点当成开始回到步骤1,若出栈元素没有右节点,回到步骤2
4.栈空即完成
(先序是在节点入栈前访问,中序是出栈后访问)
二叉树线索化:一棵二叉树,写出二叉链表,然后二叉树画图时用虚线补充,按 节点没有左子节点,就连前驱节点,节点没有右子节点,就连后继节点
线索二叉树求前驱后继:
1.先序求后继节点:如果当前节点的右指针存线索,则指向的是后继,若右指针存节点,取左节点为后继,没左节点就取右节点
2.后序求前驱节点:左指针左指针,取右节点***********
3.中序求后继:如果当前节点的右指针是线索,则指向的节点是后继;如果当前节点指向的右指针是节点,右子树的最左边节点为后继节点
中序求前驱:左*;左左右************
二叉排序树(BST)--->删除操作:1.删除根/删除叶节点,释放内存即可;2.删除只有单子树的节点,子树代替自己;3.删除有双子树的节点,找自己左子树最右侧的节点代替自己(即当前位置节点值小但又是最大的那个值),然后删除那个节点/或者找右子树最左侧的节点(比自己大又是最小的那个)
树的遍历:先根遍历等于对应二叉树的先序遍历,后根遍历是对应二叉树的中序遍历
森林的遍历:先序遍历对应二叉树的先序遍历,中序遍历对应二叉树的中序遍历
【树/森林对应的二叉树是根据儿子节点放左下,兄弟节点接右下(很多兄弟就一直右下的右下,儿子也是)】
平均查找长度ASL--->成功:每个节点要比较的平均次数(第一层比较一次,第二层比较两次,因为是从第一层走向第二层),(每层数*每层节点数)的累加除于总结点数
失败:叶节点的虚空子节点比较平均次数(叶节点的两个虚空子节点比较次数/总虚空节点)
平衡二叉树(AVL)--->平衡节点:自己左子树的高度-右子树的高度
找最小不平衡子树调整:情况一外侧子树更高,只要旋转一次;内侧转两次(先找最小不平衡树,然后退一步看有问题的那边的子树按情况1转,转完后又是情况一),哪边子树高就转哪边,先搞小的再搞大的
旋转可以理解为收儿子,A原来是B的儿子,旋转后A收B当儿子,B站了一个儿子位,那如果A的那个儿子位有人,就要送给B当另一边的儿子作为补偿
平衡二叉树的最小节点数:An = A(n-1) + A(n-2) + 1;  ---> 1 2 4 7 12 ......  [类似斐波那契数列:1 1 2 3 5 8 13 ...]
哈夫曼树(左走0,右走1)
带权路径长度:用节点的权值乘路径长度,而所有节点带权路径之和WPL最小,就是最优哈夫曼树
哈夫曼树构造:每次选两个出来相加得到新节点
红黑树规则:1.根节点为黑;2.叶节点为NULL且为黑;3.每个节点到叶子节点的所有路径,都包括相同数目的黑色节点;4.红色的孩子不能是黑的,黑的孩子节点可以黑
红黑树的插入操作:
1.只有一个根节点(红色)时直接插入,然后根节点变黑
2.父节点是黑色时,新插红色不影响
3.新节点D的父节点B和叔叔节点C都红以及根A黑时,父节点B变黑,然后根节点A变红,叔叔节点C变黑
4.新节点D的父节点B红,叔叔黑或没叔叔,且新节点D是父节点B的右孩子,父节点B是根节点A的左孩子(即不直),以B为轴左旋转,使D上升【或者D是B的右孩子,B是A的左孩子,以B为轴右旋转】,进入情况5
5.新节点D的父B红,叔叔黑或没叔叔,且D是B的左孩子,B是A的左孩子,以A为轴右旋转使B上升,操作和之前的旋转描述一样【B右D右同理】
红黑树的删除操作
1.删除红叶节点
2.待删除的叶节点D为黑,D的兄弟节点E也黑,没有侄子节点--->删除D,父变黑,E变红
3.D黑,父节点P未知,兄弟E黑,有单侄子F红--->删除D,E颜色变P颜色,P和F变黑,旋转使E上升
4.D黑,父节点P未知,兄弟E黑,有双侄子FG红--->删除D,旋转使E上升,E变P色,P和同级的那个节点变黑
5.D黑,E红,P必黑,双侄子FG黑--->删除D,旋转使E上升,E变黑,P和同级变黑
6.删除节点只有左孩子/右孩子--->待删除节点颜色不变,用孩子的值代替原值,删孩子节点
7.删除节点有双孩子--->待删除节点值换成前驱的值,然后删除前驱节点,然后按上面的情况分析
单链表:
1.按节点的前插操作(p节点前插入元素e):先判p空?分配一个新的节点内存s,将s的后继指向p的后继,再将p的后继指向s,将p的元素数据赋给s的数据区,再把元素e赋给p的数据区;
按位序的插入:先判插入位置i是否合法?然后定义节点指针p从头节点(第0个节点,不存数据)移到待插位置i的前一个,判断i-1位置的是否空?分配一个链表类型的节点指针s,元素e赋给s的数据,,s的后继指向p的后继,p的后继给s
2.查找:找值,遍历比较;找第i个
3.反转:原地翻转(翻转某个节点p之后的所有值),新建节点ss和ssnext,用ss指向p的next,然后将p的next指向空,然后在ss非空的条件下将ss插到p的后面(ssnext是存放ss的下一位地址的,用来实现递增的效果)
                    
                
                
            
        
浙公网安备 33010602011771号