二叉树

二叉树


1 树的存储结构

树结构是一种非线性存储结构,存储的是具有一对多关系的数据元素的集合。

1.1 树的节点

结点:使用树结构存储的每一个数据元素。

父结点子结点兄弟结点:对于图 1(A)中的结点 A、B、C、D 来说,A 是 B、C、D 结点的父结点(也称为“双亲结点”),而 B、C、D 都是 A 结点的子结点(也称“孩子结点”)。对于 B、C、D 来说,它们都有相同的父结点,所以它们互为兄弟结点。

根结点:每一个非空树都有且只有一个被称为根的结点,即没有父结点的一个结点。

1.2 子树和空树

树是由根结点和若干棵子树构成的。

空树:如果集合本身为空,那么构成的树就被称为空树。空树中没有结点。

1.3 结点的度和层次

结点的度(Degree):对于一个结点,拥有的子树数(结点有多少分支)。

结点的层次:从一棵树的树根开始,树根所在层为第一层,根的子结点所在的层为第二层,依次类推。

树的深度(高度):树中结点所在的最大的层次。

2 二叉树

满足以下两个条件的树就是二叉树:

  • 本身是有序树;

  • 树中包含的各个节点的度不能超过 2,即只能是 0、1 或者 2;

2.1 二叉树的性质
  • 二叉树中,第 i 层最多有 2i-1 个结点。

  • 如果二叉树的深度为 K,那么此二叉树最多有 2K-1 个结点。

  • 二叉树中,终端结点数(叶子结点数)为 n0,度为 2 的结点数为 n2,则 n0=n2+1。

2.2 满二叉树

如果二叉树中除了叶子结点,每个结点的度都为 2,则此二叉树称为满二叉树。

2.3 完全二叉树

如果二叉树中除去最后一层节点为满二叉树,且最后一层的结点依次从左到右分布,则此二叉树被称为完全二叉树。

3 二叉树的实现

3.1 顺序表实现

顺序存储只适用于完全二叉树。因此,若想顺序存储普通二叉树,需提前将普通二叉树转化为完全二叉树。完全二叉树的顺序存储,仅需从根节点开始,按照层次依次将树中节点存储到数组即可。

3.2 链表实现

采用链式存储二叉树时,其节点结构由 3 部分构成(如图 3 所示):

  • 指向左孩子节点的指针(Left);
  • 节点存储的数据(data);
  • 指向右孩子节点的指针(Right);

4 二叉查找树

4.1 初始化

二叉查找树的性质:对于树中的每个节点X,它的左子树中所有关键字的值小于X的关键字值,而它右子树中所有关键字值大于X的关键字值。

4.2 查找

find:返回指向树中数据为data的节点的指针。

findMin:返回树中数据最小值的节点的指针,从根开始且只要有左子树就向左进行,终点是最小元素。

findMax:返回树中数据最大值的节点的指针。

4.3 插入

为将data插入到树中,先进行查找,若找到值为data的节点则什么也不做,否则将data插入到遍历的路径上的最后一点上。

4.4 删除
4.5 遍历

先序遍历:访问根节点。访问当前节点的左子树。若当前节点无左子树,则访问当前节点的右子树。

中序遍历:访问当前节点的左子树,访问根节点,访问当前节点的右子树。

后序遍历:从根节点出发,依次遍历各节点的左右子树,直到当前节点左右子树遍历完成后,才访问该节点。

typedef struct TreeNode{
    int data;
    struct TreeNode *left;
    struct TreeNode *right;
}TreeNode, *Tree;
/* 初始化 */
Tree initTree(int data){
    Tree t = (Tree)malloc(sizeof(TreeNode));
    if(!t) return NULL;
    t->data = data;
    t->left = t->right = NULL;
    return t;
}
/* 查找值为data的结点 */
TreeNode *find(Tree t){
    if(!T) return NULL;
    if(data < t->data)
        return find(data, t->left);
    else{
        if(data > t->data)
            return find(data, t->right);
        else return t;
    }
}
/* 查找最大值(非递归实现) */
TreeNode *findMax(Tree t){
    if(!t) return NULL;
    while(t->right)
        t = t->right;
    return t;
}
/* 查找最小值(递归实现) */
TreeNode *findMin(Tree t){
    if(t == NULL)
        return NULL;
    if(t->left == NULL)
        return t;
    else
        return findMin(t->left);
}
/* 插入元素 */
Tree insert(int data, Tree t){
    if(!t){
        t = (Tree)malloc(sizeof(TreeNode));
        if(t) return NULL;
        else{
            t->data = data;
            t->left = t->right = NULL;
        }
    }else{
        if(data < t->data)
        	t->left = insert(data, t->left);
    	else
        if(data > t->data)
            t->right = insert(data, t->right);
    }
    return t;
}
/* 删除元素 */
void delete(int data, Tree t)
{
    TreeNode *tmp;
    if(!t) return NULL;
    t = find(data, t);
    if(t->left && t->right){
        tmp = findMin(t->right);
        t->data = tmp->data;
        t->right = delete(t->data, t->right);
    }else{
        tmp = t;
        if(!t->left) t = t->right;
        else if(!t->right) t = t->left;
        free(tmp);
    }
}
/* 先序遍历 */
void preTravel(Tree t){
    if(t != NULL){
        printf("%d", t->data);
        preTravel(t->left);
        preTravel(t->right);
    }
}
/* 中序遍历 */
void inTravel(Tree t){
    if(t != null){
        inTravel(t->left);
        printf("%d", t->data);
        inTravel(t->right);
    }
}
/* 后序遍历 */
void postTravel(Tree t){
    if(t){
        postTravel(t->left);
        postTravel(t->right);
        printf("%d", t->data);
    }
}
    inTravel(t->right);
}

}
/* 后序遍历 */
void postTravel(Tree t){
if(t){
postTravel(t->left);
postTravel(t->right);
printf("%d", t->data);
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值