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

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个空格,行末不得有多余空格。

问题:明白思路,能画出树,但在代码层面上的实现没有方向

posted @ 2020-04-26 16:04  陈-----  阅读(240)  评论(0编辑  收藏  举报