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

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

一.思维导图

J2TOED.jpg

二.重要概念的笔记

1)二叉树基本性质

1、基本性质:

(1)在二叉树的第i层上至多有2^(i-1)个节点。

(2)深度为h的二叉树上至多有2^h-1个节点。

(3)对任何一棵二叉树,若含有n0个叶子节点,n2个度为2的节点,则n0=n2+1。

(4)满二叉树:深度为k且含有2^k-1个节点的二叉树,也叫完美二叉树。

(5)完全二叉树:树中共n个节点,则该n个节点的编号与满二叉树中的节点编号一一对应。

2)四种遍历的代码
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;
}

Status LevelOrderTraverse(BiTree T)//层次遍历
{
    queue<BiTree> q;
    BiTree front;
    if (T == NULL)
        return ERROR;
    q.push(T);
    while (!q.empty()) {
        front = q.front();
        q.pop();

        if (front->lchild)
            q.push(front->lchild);
        if (front->rchild)
            q.push(front->rchild);
        if (q.size()==0)
            cout << front->data;
        else
            cout << front->data << " ";
    }
    return OK;
}
3)哈夫曼树

1、特点

(1)只有度为0和度为2的节点。

(2)因为二叉树中n2=n0-1,哈夫曼树共有2n-1个节点,其中n为叶子节点n0。

4)树、森林、二叉树的转换
树转换为二叉树

(1)加线。在所有兄弟结点之间加一条连线。

(2)去线。树中的每个结点,只保留它与第一个孩子结点的连线,删除它与其它孩子结点之间的连线。

(3)层次调整。以树的根节点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明。(注意第一个孩子是结点的左孩子,兄弟转换过来的孩子是结点的右孩子)

J2bxC4.jpg

森林转换为二叉树

(1)把每棵树转换为二叉树。

(2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子,用线连接起来

J2qKKI.jpg

二叉树转换为树

是树转换为二叉树的逆过程。

(1)加线。若某结点X的左孩子结点存在,则将这个左孩子的右孩子结点、右孩子的右孩子结点、右孩子的右孩子的右孩子结点…,都作为结点X的孩子。将结点X与这些右孩子结点用线连接起来。

(2)去线。删除原二叉树中所有结点与其右孩子结点的连线。

(3)层次调整。

J2qdrq.jpg

二叉树转换为森林

假如一棵二叉树的根节点有右孩子,则这棵二叉树能够转换为森林,否则将转换为一棵树。

(1)从根节点开始,若右孩子存在,则把与右孩子结点的连线删除。再查看分离后的二叉树,若其根节点的右孩子存在,则连线删除…。直到所有这些根节点与右孩子的连线都删除为止。

(2)将每棵分离后的二叉树转换为树。

J2q7Je.jpg

5)二叉排序树的实现
代码实现:
BSTree SearchBST(BSTree T, KeyTyped key) {
	if (!T || T->data == key) {
		return T;
	}
	if (key < T->data) {
		return SearchBST(T->lchild, key);
	}
	else {
		return SearchBST(T->rchild, key);
	}
}
bool InsertBST(BSTree& T, KeyTyped key) {
	if (!T) {
		T = new BSTNode;
		T->data = key;
		T->lchild = NULL;
		T->rchild = NULL;
		return true;
	}
	else if (key == T->data) {
		return false;
	}
	else if (key < T->data) {
		return InsertBST(T->lchild, key);
	}
	else {
		return InsertBST(T->rchild, key);
	}
}
BSTree CreateBST(KeyTyped a[], int n) {
	int i = 0;
	BSTree T = NULL;
	while (i < n) {
		InsertBST(T, a[i]);
		i++;
	}
	return T;
}

三.疑难问题及解决方案之哈夫曼树的构建

题目:给定权值{19,21,2,3,6,7,10,32}构建一颗哈夫曼树

1)从19,21,2,3,6,7,10,32中选择两个权小结点。选中2,3。同时算出这两个结点的和5

J2vwUP.jpg

2)从19,21,6,7,10,32,5中选出两个权小结点。选中5,6。同时计算出它们的和11

J2vcuj.jpg

3)从19,21,7,10,32,11中选出两个权小结点。选中7,10。同时计算出它们的和17
*(P.s. 这时选出的两个数字都不是原来的二叉树里面的结点,所以要另外开一棵二叉树)

J2vbr9.jpg

4)从19,21,32,11,17中选出两个权小结点。选中11,17。同时计算出它们的和28

J2vXUx.jpg

5)从19,21,32,28中选出两个权小结点。选中19,21。同时计算出它们的和40。 另起一颗二叉树

J2xCKH.jpg

6)从32,28, 40中选出两个权小结点。选中28,32。同时计算出它们的和60

J2x8I0.jpg

7)从 40, 60中选出两个权小结点。选中40,60。同时计算出它们的和100

J2xaM4.jpg

P.s. 上次做作业的时候,我构造哈弗曼树就是一直从剩下的结点里面找权值最小的,然后添加上去,而没有考虑构造出来的和权值的大小问题,导致哈夫曼树构造错误!

posted @ 2020-04-26 21:58  Sogger  阅读(157)  评论(0编辑  收藏  举报