树,二叉树,查找算法总结

一.思维导图


二.重要概念的笔记

树和二叉树

1. 有序树:子树之间存在确定的次序关系(树中结点的各子树从左到右是有次序的,即不能互换)

2. 无序树:子树之间不存在确定的次序关系

3. 在二叉树的第i层至多有2(i-1)个结点

4. 深度为K的二叉树上至多有2k-1个结点

5. 对任意二叉树,若它有n0个叶子结点,n2个度为2的结点,则n0=n2+1

6. 树的后根遍历与对应二叉树的中根遍历顺序是一致的

7. 用二叉链表存储具有n个结点的二叉树时,指针总数为2n,其中n-1个指向孩子,n+1个指针是空闲的

8. 平均查找长度与树的形态有关,最好:log2n;最坏:(n+1)/2(单支树)

哈弗曼树

1. 具有n个叶子结点的哈弗曼树共有2n-1个结点

2. 就有相同带权结点的哈夫曼树不唯一

B-树和B+树

1. m阶B-树的非根节点的孩子个数最多有m个,最少有m/2个,关键字个数最多有m-1个,最少有m/2-1个;

2. 计算B-树的高度时,需要计入最底层的外部结点

3. m阶B+树的每个分支结点至多有m棵子树,有n棵子树的节点有n个关键字

4. B+树中所有叶子结点包含了全部关键字

查找

1. 折半查找:适合对象——只是适用于有序表,且限于顺序存储结构(线性链表无法进行折半查找);时间复杂度:T(n) =O(log2n)

1. 除留余数法:H(key)%p;(p可选小于表长的最大质数)

2. 设哈希函数H(key)=key MOD p(表长=p),处理冲突:Hi=(H(key)+di) MOD p;线性探测再散列:di=c*i;二次探测再散列:di=12,(-1)2,22,(-2)2,...+k2-k2(k<=m/2)

3.疑难问题及解决方案

1.一开始对B-树的插入不太了解,后来通过查看老师的ppt理解了:

关键字插入位置必须为叶子结点层,若插入后该结点的关键字个数n<m-1,则不需要修改指针;若插入后该结点的关键字个数n>m-1,则进行结点分裂;分裂时将插入结点后该结点处的中间位置关键字ki提出,若没有双亲结点,则新建一个双亲结点,将ki插入其中,树的高度增加一层;若有双亲结点,将ki插入双亲结点中;以此类推

2.PTA这道题不是很懂,百度找到了答案但是不怎么懂

void InitExpTree(BTree &T,string str){
stack<BTree> Tree;
stack<char> ch;
int i=0;
ch.push('#');
while(str[i]){
if(!In(str[i])){
T=new BTNode;
T->data=str[i++];
T->lchild=NULL;
T->rchild=NULL;
Tree.push(T);
}
else{
if(Precede(ch.top(),str[i])=='<'){
ch.push(str[i]);
i++;
}
else if(Precede(ch.top(),str[i])=='='){
ch.pop();
i++;
}
else{
T=new BTNode;
T->data=ch.top();
T->rchild=Tree.top();
Tree.pop();
T->lchild=Tree.top();
Tree.pop();
Tree.push(T);
ch.pop();
}
}
}
while(ch.top()!='#'){
T=new BTNode;
T->data=ch.top();
T->rchild=Tree.top();
Tree.pop();
T->lchild=Tree.top();
Tree.pop();
Tree.push(T);
ch.pop();
}
T=Tree.top();
}
double EvaluateExTree(BTree T){
double sum=0,a,b;
if(!T->rchild&&!T->lchild){
return T->data-'0';
}
a=EvaluateExTree(T->lchild);
b=EvaluateExTree(T->rchild);
switch(T->data){
case '+':return a+b;
case '-':return a-b;
case '*':return a*b;
case '/':if(b==0){
cout<<"divide 0 error!";
exit(0);
}
return a/b;
}
}
posted @ 2020-04-26 15:01  Vancciiii  阅读(254)  评论(0编辑  收藏  举报