完全二叉树(详细代码)

一、二叉树

是每个结点最多有两个子树的有序树,是树的一种。

二叉树的特性:

1. 子树有左右之分,次序不能颠倒

2. 第i层最多有2^(i-1)个节点

3. 深度为k的二叉树至多有2^(k)-1个节点

4. 如果度为2的节点数为n,度为0的节点数为m,则m = n + 1

二、满二叉树

 是二叉树的一种特殊的情况

 满二叉树的特性:

1. 第i层上的节点数必须为2^i个节点

2. 高度为k,节点数必须为2^(k+1)-1个节点

3. 有可能空间浪费太大

三、完全二叉树

也是二叉树的一种特殊情况 

满二叉树是完全二叉树,完全二叉树不一定是满二叉树 

 完全二叉树的特性:

1. 根节点下标默认为0

2. 任意节点下标为i,则其父节点下标为(i -1)>>1

3. 任意节点下标为i,则其左子树下标为2*i + 1 ,右子树下标为2*i + 2

四、代码示例(完全二叉树)

1. 二叉树结构

template<typename T>
class TreeArr
{
    T *pBuff;//数组实现完全二叉树
    T len;//长度
    T Maxsize;//最大容量
}

2. 基本函数

public:
    TreeArr();//构造函数
    ~TreeArr();//析构函数
    void clear();//清空二叉树
    void InitTree(T arr [],int lenght);//构造二叉树
    void append(T const & data);//尾部插入
    bool find(T const & findData) const;//查找函数
    void printfTree();//输出二叉树
private:
    int _find(T const & findData) const;//内部查找函数
    void _printfTree(int Index);//内部输出函数

3. 内部查找函数

template<typename T>
int TreeArr<T>::_find(T const & findData) const
{
    for (int i = 0; i < len; i++)
    {
        if (pBuff[i] == findData)
        {
            return i;
        }
    }
    return -1;
}

4. 内部输出函数

template<typename T>
void TreeArr<T>::_printfTree(int Index)
{
    // if (Index<0 || Index>=len)
    // {
    //     return;
    // }
    if (Index < len)
    {
        printf("%d\n",pBuff[Index]);//先序
        _printfTree(Index*2 + 1);
        // printf("%d\n",pBuff[Index]);//中序
        _printfTree(Index*2 + 2);
        // printf("%d\n",pBuff[Index]);//后序
    }
}

5. 查找函数

template<typename T>
bool TreeArr<T>::find(T const & findData) const
{
    return _find(findData) != -1;
}

6. 输出函数

template<typename T>
void TreeArr<T>::printfTree()
{
    _printfTree(0);
}

7. 构造二叉树函数

template<typename T>
void TreeArr<T>::InitTree(T arr [],int lenght)
{
    clear();//必须先清除

    if (lenght > 0)
    {
        Maxsize = len = lenght;
        pBuff = new T [Maxsize];
        for (int i = 0; i < len; i++)
        {
            pBuff[i] = arr[i];
        }
    }
}

8. 尾部插入函数

template<typename T>
void TreeArr<T>::append(T const & data)
{
    if (len >= Maxsize)
    {
        Maxsize += ((Maxsize>>1 > 1) ? Maxsize>>1 : 1);
        T *tempBuff = new T[Maxsize];//动态开辟辅助数组
        for (int i = 0; i < len; i++)
        {
            tempBuff[i] = pBuff[i];
        }
        if (pBuff)
        {
            delete[] pBuff;//清空原数组
        }
        pBuff = tempBuff;//把辅助数组拷贝到原数组
    }
    pBuff[++len] = data;//尾部插入
}

9. 清空二叉树函数

template<typename T>
void TreeArr<T>::clear()
{
    if (pBuff)
    {
        delete [] pBuff;
    }
    pBuff = nullptr;
    len = Maxsize = 0;
}

10.构造析构函数

template<typename T>
TreeArr<T>::TreeArr()
{
    pBuff = nullptr;
    len = Maxsize = 0;
}
template<typename T>
TreeArr<T>::~TreeArr()
{
    clear();
}
要判断一棵二叉树是否为完全二叉树,我们需要检查以下条件: 1. 完全二叉树的每个层级都是满的,除了最后一个层级可能不满,但所有节点都尽可能地靠左排列。 2. 如果存在最后一层,则最后一层的所有节点都在左边。 这里有一个简单的C++代码实现,使用深度优先搜索(DFS)遍历二叉树并记录节点的数量,同时跟踪当前层级: ```cpp #include <iostream> using namespace std; // 定义二叉树节点 struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; // 判断是否为完全二叉树 bool isCompleteBinaryTree(TreeNode* root) { if (root == nullptr) return true; // 空树视为完全二叉树 int level = 0, count = 1, node = root; while (node != nullptr) { ++level; if (node->left != nullptr && node->right != nullptr) { // 如果左右子节点都存在,更新计数器 count += 2; } else { // 否则,只增加1 count++; } node = node->left ? node->right : node->left ? node->left : nullptr; // 跟踪下一个节点 } // 遍历结束后,检查是否存在不满足完整性的节点 for (int i = 1; i < level; ++i) { if (count % 2 == 1) { // 偶数层级表示满,奇数层级可能存在未填充节点 if ((count - 1) / 2 < pow(2, i)) { // 不满足完全二叉树条件 return false; } } else { if (count < pow(2, i + 1)) { // 最后一层,检查所有节点是否都在左侧 return false; } } count /= 2; } return true; } int main() { // 测试用例 TreeNode* root = new TreeNode(1); root->left = new TreeNode(2); root->right = new TreeNode(3); root->left->left = new TreeNode(4); root->left->right = new TreeNode(5); cout << (isCompleteBinaryTree(root) ? "是" : "否") << endl; // 输出:是 // ... 更多测试用例... return 0; } ``` 这个代码首先检查根节点,然后递归遍历二叉树。对于每一层,如果左右都有节点,则数量翻倍;否则,数量加一。遍历完成后,根据规则检查每层节点数量是否满足完全二叉树的定义。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你怎么知道我头发乌黑浓密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值