文章目录
树
定义:
(1)有且仅有一个根节点
(2)每个子节点及其分支也满足数的定义
二叉树
普通二叉树
基本元素:
1.节点:根节点、左节点、右节点、叶子节点
2.路径:从根节点到目标节点经过的边
3.层次:和根节点经过同样长度的路径构成的层次结构
4.深度:最长路径的长度
遍历方式:
1.先序遍历(DLR):
递归方式:
void pre_order(PNODE root)
{
if(root == NULL)
{
return;
}
printf("%d-", root->data);
pre_order(root->left);
pre_order(root->right);
}
非递归方式:
void pre_order_other(PNODE root)//先序遍历非递归
{
STACK *Shead = create_stack();
while(1)
{
while(root)
{
printf("%d--", root->data);
push(Shead, root);
root = root->left;
}
if(empty(Shead))
{
break;
}
root = pop(Shead);
root = root->right;
}
}
2.中序遍历(LDR):
递归方式:
void mid_order(PNODE root)
{
if(root == NULL)
{
return;
}
mid_order(root->left);
printf("%d-", root->data);
mid_order(root->right);
}
非递归方式:
void mid_order_other(PNODE root)//中序遍历非递归
{
STACK *Shead = create_stack();
while(1)
{
while(root)
{
push(Shead, root);
root = root->left;
}
if(empty(Shead))
{
break;
}
root = pop(Shead);
printf("%d--", root->data);
root = root->right;
}
}
3.后序遍历(LRD):
递归方式:
void back_order(PNODE root)
{
if(root == NULL)
{
return;
}
back_order(root->left);
back_order(root->right);
printf("%d--", root->data);
}
4.层次遍历:
void levelorder(PNODE root)//层次遍历
{
PNODE temp;
QUEUE *Q = create_queue();
if(!root)
{
return;
}
enqueue(Q, root);
while(!empty_DL(Q))
{
temp = dequeue(Q);
printf("%d---", temp->data);
if(temp->left)
{
enqueue(Q, temp->left);
}
if(temp->right)
{
enqueue(Q, temp->right);
}
}
}
特殊二叉树
(一).空树
根节点为空
(二).只有一个根节点的树
(三).满二叉树
不通过增加层次,不能够再添加节点的树,每个层次的节点数量已达到最大值 2^深度-1
(四).完全二叉树
除最底层外,其上层是一棵满二叉树,且最底层的节点都是从左边填满的
高级二叉树
(一).哈夫曼树
一:相关概念
1.最优二叉树————————带权路径最小。
2.一堆数据要构成哈夫曼树,所有的数据应当是叶子节点。
3.WPL(带权路径长度)= 节点权值*路径长度之和。
二:哈夫曼树的实现
1.用优先队列实现哈夫曼树
代码见链接
https://blog.csdn.net/weixin_44125246/article/details/106283198
2.二叉堆实现哈夫曼树
(二).查找二叉树
定义:以根节点为标准,比根节点查找值小的,放在根节点左边,
比根节点大的,放在根节点右边。
另外:LDR的遍历方式可以直接输出排序结果。查找二叉树又名排序二叉树
c语言代码实现见链接:[c语言实现查找二叉树]
(https://blog.csdn.net/weixin_44125246/article/details/106282656)
平衡二叉树
定义:在查找二叉树的基础之上,具备一定的平衡条件。
平衡条件要容易保持,具备一定的特性。
AVL树
定义:在查找二叉树的基础上,形成左右子树高度差不超过1的平衡条件的树。
AVL树=查找二叉树+优先级队列(平衡条件);
保持平衡的四种方式:
(1)LL:左旋
void LeftRotate(ppNode root)
{
pNode cur,rc;
cur = *root;
rc = cur->right;
cur->right = rc->left;
rc->left = cur;
*root = rc;
cur->height = MAX(GetHeight(cur->left), GetHeight(cur->right))+1;
rc->height = MAX(GetHeight(rc->left), GetHeight(rc->right))+1;
}
(2)RR:右旋
void RightRotate(ppNode root)
{
pNode cur,lc;
cur = *root;
lc = cur->left;
cur->left = lc->right;
lc->right = cur;
*root = lc;
cur->height = MAX(GetHeight(cur->left), GetHeight(cur->right))+1;
lc->height = MAX(GetHeight(lc->left), GetHeight(lc->right))+1;
}
(3)LR:左右旋(先左旋再右旋)
(4)RL:右左旋(先右旋再左旋)