树、二叉树、查找算法总结
1.思维导图
2.重要概念的笔记
树的性质:
1.树中的节点数等于所有节点的度数加1
2.度为m的树中第i层最多又m^(i-1)个节点(i>=1)
3.高度为h的m次树最多又(m^h-1)/(m-1)个节点
4.具有n个节点的m次数的最小高度为logm(n(m-1)+1) 向上取整
树转换为森林:
左孩子右兄弟
二叉树的性质:
1.非空二叉树的叶子节点树等于双分支节点数加1
2.非空二叉树的第i层上最多有2^(i-1)个节点(i>=1)
3.高度为h的二叉树最多有2^h-1个节点(h>=1)
4.编号为i的节点若有左孩子,则左孩子编号为2i;有右孩子,其右孩子编号为2i+1;除根节点外节点其双亲编号为i/2
5.具有n个节点的完全二叉树的高度为(log2 n) +1;
二叉树的遍历:
//先序遍历
Status PreOrderTraverse(BiTree T){
if (T != NULL){
cout << T->data;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
return OK;
}
//中序遍历
Status InOrderTraverse(BiTree T){
if (T != NULL){
InOrderTraverse(T->lchild);
cout << T->data;
InOrderTraverse(T->rchild);
}
return OK;
}
//后序遍历
Status PostOrderTraverse(BiTree T){
if (T != NULL){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout << T->data;
}
return OK;
}
//层次遍历
void levelOrder(BinTree T) {
queue<BinTree> q;
q.push(T);
while (q) {
cout << q.front().data;
q.pop();
if (T->Right) q.push(T->Right);
if (T->Left) q.push(T->Left);
T = q.front();
}
}
二叉树的创建
Status CreateBiTreeFromString(BiTree &T, string str, int &index){
char ch;
if (index <= str.size() - 1)
ch = str[index++];
else
ch = '#';
if (ch == NULL) ch = '#';
if (ch == '#' || ch == ' ') T = NULL;
else{
if (!(T = (BiTNode*)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
T->data = ch;
CreateBiTreeFromString(T->lchild, str, index);
CreateBiTreeFromString(T->rchild, str, index);
}
return OK;
}
二叉排序树的创建:
BinTree Insert(BinTree BST, ElementType X) {
if (BST == NULL) {
BST = (BinTree)malloc(sizeof(struct TNode));
BST->Data = X;
BST->Left = BST->Right = NULL;
}
else {
if (X > BST->Data) BST->Right = Insert(BST->Right, X);
else if (X < BST->Data) BST->Left = Insert(BST->Left, X);
}
return BST;
}
二叉排序树的查找:
Position Find(BinTree BST, ElementType X) {
while (BST) {
if (X < BST->Data) {
BST = BST->Left;
}
else if (X > BST->Data) {
BST = BST->Right;
}
else return BST;
}
return NULL;
}
二叉排序树的删除:
BinTree Delete(BinTree BST, ElementType X) {
BinTree temp;
if (BST == NULL)//x不存在
{
printf("Not Found\n");
}
else {
if (X == BST->Data) {//找到x
if (BST->Right && BST->Left) {//有左右孩子
temp = FindMax(BST->Left);
BST->Data = temp->Data;
BST->Left = Delete(BST->Left,temp->Data);
}
else {
temp = BST;
if (!BST->Left) BST = BST->Right;//有右孩子或叶子节点
else if (!BST->Right) BST = BST->Left;//有左孩子
free(temp);
}
}
else if (X > BST->Data) BST->Right = Delete(BST->Right, X);
else BST->Left = Delete(BST->Left, X);
}
return BST;
}
Position FindMax(BinTree BST) {//找左子树最右节点
BinTree p;
p = (BinTree)malloc(sizeof(struct TNode));
p = NULL;
while (BST) {
p = BST;
BST = BST->Right;
}
return p;
}
B树与B+树
B树
1.m阶B树的非根节点的孩子个数最多有m个,最少有m/2(向上取整)个
2.关键字个数最多有m-1个,最少有m/2-1个
◼ B-树的插入:
在查找不成功之后,需进行插入。关键字****插入的位
置必定在叶子结点层,有下列几种情况:
插入后,该结点的关键字个数n<m-1,不修改指针;
插入后,该结点的关键字个数 n=m-1,则需进行结点分裂
分裂过程:
1.如果没有双亲结点,新建一个双亲结点,树的高度增加一层。
2.如果有双亲结点,将k(i下标)插入到双亲结点中。
B-树的删除:和插入的考虑相反,
首先必须找到待删关键字所在结点,并且要求删除
之后,结点中关键字的个数不能小于m/2-1;否则,
要从其左(或右)兄弟结点“借调”关键字,若其左
和右兄弟结点均无关键字可借(结点中只有最少量
的关键字),则必须进行结点的“合并”。
B+树
1.m阶B+树的每个分支节点至多有m棵子树
2.有n棵子树的节点有n个关键字
3.叶子节点包含全部关键字及指向相应记录的指针
4.可以顺序查找,不同于b+树。
哈希查找
处理冲突的方法:开放定址,链地址法
链地址法:将所有哈希地址相同的记录都链接在同一链表中
决定哈希表查找的ASL的因素: 选用的哈希函数 选用的处理冲突的方法 哈希表饱和的程度,装载因子(a=n/m)值的大小(n:记录数,m:表的长度)
3.疑难问题及解决方案(如果有的话,不求多但求精。可包含编程题,可只包含无解决方案的疑难问题)
本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。
输入格式:
第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。
输出格式:
在一行中输出Preorder:
以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。
问题:明白思路,能画出树,但在代码层面上的实现没有方向