树、二叉树、查找算法总结
树、二叉树、查找算法总结
一.思维导图
二.重要概念的笔记
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)层次调整。以树的根节点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明。(注意第一个孩子是结点的左孩子,兄弟转换过来的孩子是结点的右孩子)
森林转换为二叉树
(1)把每棵树转换为二叉树。
(2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子,用线连接起来
二叉树转换为树
是树转换为二叉树的逆过程。
(1)加线。若某结点X的左孩子结点存在,则将这个左孩子的右孩子结点、右孩子的右孩子结点、右孩子的右孩子的右孩子结点…,都作为结点X的孩子。将结点X与这些右孩子结点用线连接起来。
(2)去线。删除原二叉树中所有结点与其右孩子结点的连线。
(3)层次调整。
二叉树转换为森林
假如一棵二叉树的根节点有右孩子,则这棵二叉树能够转换为森林,否则将转换为一棵树。
(1)从根节点开始,若右孩子存在,则把与右孩子结点的连线删除。再查看分离后的二叉树,若其根节点的右孩子存在,则连线删除…。直到所有这些根节点与右孩子的连线都删除为止。
(2)将每棵分离后的二叉树转换为树。
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
2)从19,21,6,7,10,32,5中选出两个权小结点。选中5,6。同时计算出它们的和11
3)从19,21,7,10,32,11中选出两个权小结点。选中7,10。同时计算出它们的和17
*(P.s. 这时选出的两个数字都不是原来的二叉树里面的结点,所以要另外开一棵二叉树)
4)从19,21,32,11,17中选出两个权小结点。选中11,17。同时计算出它们的和28
5)从19,21,32,28中选出两个权小结点。选中19,21。同时计算出它们的和40。 另起一颗二叉树
6)从32,28, 40中选出两个权小结点。选中28,32。同时计算出它们的和60
7)从 40, 60中选出两个权小结点。选中40,60。同时计算出它们的和100
P.s. 上次做作业的时候,我构造哈弗曼树就是一直从剩下的结点里面找权值最小的,然后添加上去,而没有考虑构造出来的和权值的大小问题,导致哈夫曼树构造错误!