树是什么
树是n个节点的有限集
(1)有且只有一个节点的称为根节点
(2)当n>1时,其他节点可以分为m个不相交的有限集,并且称为根的子树
度
节点拥有的子树个数为该节点的度
树的度为各结点中度最大的值
叶子
度为0的结点称为叶子结点/终端结点
深度/高度
树中结点的最大层次
有序/无序树
有序:有左右自分,有次序
无序:反之
二叉树是什么
特点:
1、每个节点至多只有两个子节点。
2、二叉树中不存在度大于2的节点。
3、二叉树有左右之分,其次序不能颠倒
性质:
1、在二叉树的第i层上至多有2^(i-1)
个结点(i>=1)
2、深度为k的二叉树至多有2^k-1
个结点(k>=1)
3、叶子树为n0、度为2的节点数为n2.则n0=n2+1
4、结点总数为n=n1+n2+n0
5、设B为分支总数,则n=B+1 B=n1+2n2
所以得n=n1+2n2+1
满二叉树
每一层上的结点数都是最大节点数
完全二叉树
对满二叉树按顺序从 头到尾编号,深度为K,当且仅当编号和每个结点都一一对应。
(1)叶子结点只可能在层次最大的两层上出现
(2)对于任一节点。如果他的右分支的子孙的最大层次为L,则其左分支下的子孙最大层次为L或者L+1
具有n个结点的完全二叉树的深度为(log2n)+1
(3)对于完全二叉树的任一结点i。若i=1,则无双亲为根节点。诺i>1则他的双=双亲是i/2
(4)诺2i>n
,则结点i没有左孩子,否则特左孩子结点是2i
(5)诺2i+1>n
则无右孩子,否则右孩子结点是2i+1
二叉树的存储结构
typedef struct BiTNode {
TElemType data;//定义该结点的数据
struct BiTNode *lchild, *rchild;//添加左孩子和右孩子指针
}BiTNode,*BiTree;
错误写法:
原因:lchild
和rchild
在没有定义BiNode
的情况下使用了BiTNode
由于需要在结构体中定义一个同样类型的指针。所以在struct后面必须要添加结构体名。否则后面会报错。
typedef struct{
TElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode,*BiTree;
二叉树的遍历/空/根/叶子
采用的是递归的方法
先序遍历
先遍历根节点后左右结点
中序遍历
先遍历左节点后根右结点
后序遍历
先遍历左节点后右根结点
Status CreateTree(BiTree &T)
{
//采用先序次序来初始化
//先根节点然后左右节点
char ch;
scanf("%c", &ch);
getchar();//这里getchar是为了输入一个enter键!
//如果不加getchar,系统会把enter当作一个字符加进去
if (ch == ' ')T = NULL;//如果当前输入的为空格
//则此节点为空
else {
T = (BiTNode*)malloc(sizeof(BiTNode));
T->data = ch;
printf("--------------开始初始化%c的左子树---------------\n",ch);
CreateTree(T->lchild);
printf("-------------开始初始化%c的右子树----------------\n",ch);
CreateTree(T->rchild);
}
return 1;
}
bool BiTreeEmpty(BiTree T) {
if (T == NULL)
return true;
return false;
}
int visit(TElemType e){
printf("%c\t", e);
return 1;
}
Status PreOrderTraverse(BiTree T, int(*visit)(TElemType e)) {
if (T) {
if (visit(T->data))//根
if (PreOrderTraverse(T->lchild, visit))//左
if (PreOrderTraverse(T->rchild, visit))//右
return 1;
return -1;
}else
return -1;
}
Status InOrderTraverse(BiTree T, int(*visit)(TElemType e)) {//左根右
if (T) {
if (PreOrderTraverse(T->lchild, visit))//左
if (visit(T->data))//根
if (PreOrderTraverse(T->rchild, visit))//右
return 1;
return -1;
}
else
return -1;
}
Status PostOrderTraverse(BiTree T, int(*visit)(TElemType e)) {//左根右
if (T) {//如果树不空
if (PostOrderTraverse(T->lchild, visit))//左
if (PostOrderTraverse(T->rchild, visit))//右
if (visit(T->data))//根
return 1;
return -1;
}
else
return -1;
}
int CoutLeaf(BiTree T)
{
if (T == NULL) return 0;
if (T->lchild == NULL && T->rchild == NULL)
//一直找到底
//然后一层一层返回
{
return 1;
}
else {
int n1 = CoutLeaf(T->lchild);
int n2 = CoutLeaf(T->rchild);
return n1 + n2;
}
}
int TreeDepth(BiTree T)
{
int deep = 0;
if (T)
{
int left = TreeDepth(T->lchild);
int right = TreeDepth(T->rchild);
deep = left >= right ? left + 1 : right + 1;
}
return deep;
}
char Root(BiTree T) {
if (T == NULL)return -1;
return T->data;
}