数据结构二叉树笔记c++

个人学习所记笔记,如有错误请见谅

内容为二叉树的结点插入操作,先序中序后序层次遍历操作
代码所展示的为大体框架,可根据题目对相应代码部分进行修改

求树的高度以及宽度

求WPL

求高度

  • 时间复杂度O(n),因为每个节点被访问一次。
  • 空间复杂度O(h),其中 h 是树的高度,这由递归栈深度决定。

求宽度

  • 时间复杂度O(n),其中 n 是树中的节点数。每个节点会被入队和出队一次。
  • 空间复杂度O(w),其中 w 是树的最大宽度。队列的空间使用与当前层的节点数量有关。

求WPL

  • 时间复杂度: (O(n)),其中,(n) 是树中节点的总数。因为每个节点最多被访问一次,不管它是叶子节点还是内部节点。
  • 空间复杂度: (O(h)),其中 (h) 是树的高度,最坏情况下为 (O(n))(对于完全不平衡的树)。

这些复杂度分析表明,CalculateWPL 方法在实际应用中对大多数树的处理是高效的,但在处理高度不平衡的树时,空间复杂度可能会较高。

代码如下
 

#include <iostream>
#include <queue>
using namespace std;

//二叉树的链式存储结构
typedef struct BiTNode {
	int data;
	struct BiTNode* lchild, * rchild;
}BiTNode,*BiTree;

// 初始化二叉树
void InitTree(BiTree& T) {
    T = nullptr; // 初始化为空树
}

// 插入节点
void InsertNode(BiTree& T, int value) {
    if (T == nullptr) {
        // 如果树为空,创建根节点
        T = new BiTNode;
        T->data = value;
        T->lchild = nullptr;
        T->rchild = nullptr;
        return;
    }

    // 使用层序遍历找到第一个没有两个孩子的节点
    queue<BiTNode*> q;
    q.push(T);

    while (!q.empty()) {
        BiTNode* node = q.front();
        q.pop();

        // 如果左孩子为空,插入到左孩子
        if (node->lchild == nullptr) {
            node->lchild = new BiTNode;
            node->lchild->data = value;
            node->lchild->lchild = nullptr;
            node->lchild->rchild = nullptr;
            return;
        }
        else {
            q.push(node->lchild);//将现有左子节点加入队列
        }

        // 如果右孩子为空,插入到右孩子
        if (node->rchild == nullptr) {
            node->rchild = new BiTNode;
            node->rchild->data = value;
            node->rchild->lchild = nullptr;
            node->rchild->rchild = nullptr;
            return;
        }
        else {
            q.push(node->rchild);
        }
    }
}
//先序遍历显示
void visit(BiTree root) {
    cout << root->data << " ";
}
void PreOrder(BiTree root) {
    
    if (root != nullptr) {
        visit(root);
       // cout << root->data << " ";
        PreOrder(root->lchild);
        PreOrder(root->rchild);
    }
}
//中序遍历显示
void inorderTraversal(BiTree root) {
    
    if (root != nullptr) {
        inorderTraversal(root->lchild);
        cout << root->data << " ";
        inorderTraversal(root->rchild);
    }
}
//后序遍历
void PostOrder(BiTree root) {

    if (root != nullptr) {
        PostOrder(root->lchild);
       
        PostOrder(root->rchild);
        cout << root->data << " ";
    }
}

//层序遍历
// 层序遍历显示
void LevelOrder(BiTree root) {
    if (root == nullptr) return;

    queue<BiTNode*> q;
    q.push(root);

    while (!q.empty()) {
        BiTNode* node = q.front();
        q.pop();

        cout << node->data << " ";

        // 将左右孩子节点加入队列
        if (node->lchild != nullptr) {
            q.push(node->lchild);
        }
        if (node->rchild != nullptr) {
            q.push(node->rchild);
        }
    }
}

// 计算树的高度
//这段代码适用于所有类型的二叉树,包括普通二叉树。
// 它通过递归计算每个子树的高度,并返回左右子树中较大的高度加上 1,代表当前节点的高度。
// 无论树是否完全二叉,这种方法都能正确地计算出树的高度。
int TreeHeight(BiTree root) {
    if (root == nullptr) return 0;
    int leftHeight = TreeHeight(root->lchild);
    int rightHeight = TreeHeight(root->rchild);
    return max(leftHeight, rightHeight) + 1;
}


// 计算树的宽度
int TreeWidth(BiTree root) {
    if (root == nullptr) return 0;

    int maxWidth = 0;
    queue<BiTree> q;
    q.push(root);

    while (!q.empty()) {
        int levelSize = q.size(); // 当前层的节点数
        maxWidth = max(maxWidth, levelSize);

        // 处理当前层的所有节点
        for (int i = 0; i < levelSize; ++i) {
            BiTree node = q.front();
            q.pop();
            if (node->lchild != nullptr) q.push(node->lchild);
            if (node->rchild != nullptr) q.push(node->rchild);
        }
    }

    return maxWidth;
}

// 计算树的 WPL
void CalculateWPL(BiTree root, int depth, int& wpl) {
    if (root == nullptr) return;

    // 如果是叶子节点
    if (root->lchild == nullptr && root->rchild == nullptr) {
        wpl += root->data * depth;
    }
    else {
        // 递归计算左右子树
        CalculateWPL(root->lchild, depth + 1, wpl);
        CalculateWPL(root->rchild, depth + 1, wpl);
    }
}
int main()
{
    BiTree T;
    InitTree(T);

    InsertNode(T, 1);
    InsertNode(T, 2);
    InsertNode(T, 3);
    InsertNode(T, 4);
    InsertNode(T, 5);
    InsertNode(T, 6);
    InsertNode(T, 7);

    cout << "先序: ";
    PreOrder(T);
    cout << endl;

    cout << "中序: ";
    inorderTraversal(T);
    cout << endl;

    cout << "后序: ";
    PostOrder(T);
    cout << endl;

    cout << "层序: ";
    LevelOrder(T);
    cout << endl;

    cout << "树的高度为:" << TreeHeight(T)<<endl;

    cout << "树的宽度为:" << TreeWidth(T) << endl;

    int wpl = 0;
    CalculateWPL(T, 0, wpl);
    cout << "树的 WPL 为: " << wpl << endl;
	return 0;
}

运行结果如下

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值