欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 八卦 > 数据结构——树

数据结构——树

2025/4/19 5:31:21 来源:https://blog.csdn.net/m0_67428211/article/details/144043959  浏览:    关键词:数据结构——树

参考:数据结构(C++版)第2版 [王红梅]

文章目录

  • 树和二叉树
    • 基本术语
    • 二叉树概念
    • 二叉树的性质
    • 二叉树的存储
      • 顺序存储
      • 二叉链表
    • 二叉树的遍历
      • 广度遍历
      • 深度遍历

树和二叉树

基本术语

  • 结点的度、树的度:某结点拥有子树的个数为该结点的度(degree),各节点中度最大的值为树的度
  • 叶子结点、分支节点:度等于0的结点为叶子节点(leaf node),度不等于0的结点为分支节点(branch node)
  • 结点的层数、树的深度:根节点的层数为1,其孩子节点的层数为k + 1层,层数的最大值为树的深度

二叉树概念

  • 满二叉树
    所有分支结点都存在左右子树,所有叶子结点都在同一层,这样的二叉树称为满二叉树
    在这里插入图片描述

  • 完全二叉树
    叶子结点只能出现在最后两层上,最后一层的叶子结点都集中在二叉树的左侧。度为1的结点只可能有一个,且这个结点只有左孩子。
    在这里插入图片描述

二叉树的性质

  • 第 i 层最多有 2^(i - 1) 个结点 (i >= 1)
  • 在深度为 k 的二叉树中,最少有 k 个结点,最多有 2^k - 1
  • 二叉树中叶子结点的个数为n0,度为2的结点为n2,则n0 = n2 + 1
  • 具有n个结点的完全二叉树的深度为 在这里插入图片描述
  • 对于完全二叉树,从根节点开始进行编号,对于任意为 i 编号的结点有
    1. i > 1,则 i 的双亲结点编号为 i / 2
    2. 2i <= n,则 i 的左孩子为 2i
    3. 2i + 1<= n,则 i 的右孩子为 2i + 1

二叉树的存储

顺序存储

用数组来映射二叉树的编号,将二叉树按照完全二叉树进行编号,根据二叉树的性质进行映射
在这里插入图片描述

二叉链表

插入结点,按照层序插入

void AddNode(int val)
{TreeNode* node = new TreeNode(val);if (!root){root = node;return;}queue<TreeNode*> qu;qu.push(root);while (!qu.empty()){TreeNode* t = qu.front();qu.pop();if (t->left) qu.push(t->left);else{t->left = node;return;}if (t->right) qu.push(t->right);else{t->right = node;return;}}
}

二叉树的遍历

广度遍历

广度遍历即层序遍历

void LeverOder(TreeNode* node)
{if (node == nullptr) return;queue<TreeNode*> q;q.push(node);while (!q.empty()){TreeNode* t = q.front();q.pop();q.push(t->left);q.push(t->right);cout << t->val << " ";}
}

深度遍历

深度遍历有前序遍历、中序遍历、后续遍历

1.前序遍历根结点 → 左子树 → 右子树

  • 递归方法:
void PreOder(TreeNode* node)
{if (node == nullptr) return;cout << node->val << " ";PreOder(node->left);PreOder(node->right);
}
  • 非递归方法:使用栈
void PreOder(TreeNode* root)
{vector<int> vec;stack<TreeNode*> st;st.push(root);while (!st.empty()){TreeNode* tnode = st.top();vec.push_back(tnode->val);st.pop();if (tnode->right != nullptr) st.push(tnode->right);if (tnode->left != nullptr) st.push(tnode->left);}
}

2.中序遍历:左子树→ 根结点 → 右子树

递归方法:

void InOder(TreeNode* node)
{if (node == nullptr) return;PreOder(node->left);cout << node->val << " ";PreOder(node->right);
}

非递归方法:

void InOrder(TreeNode* root)
{vector<int> vec;stack<TreeNode*> st;TreeNode* tnode = root;while (!st.empty() || tnode != nullptr){if (tnode != nullptr){st.push(tnode);tnode = tnode->left;}else{TreeNode* top = st.top();st.pop();vec.push_back(top->val);tnode = top->right;}}
}

3.后序遍历:左子树 → 右子树 → 根结点

递归方法:

void InOder(TreeNode* node)
{if (node == nullptr) return;PreOder(node->left);cout << node->val << " ";PreOder(node->right);
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词