前言
这一期我一起学习初级数据结构——二叉树,
二叉树是一种非常基础且重要的数据结构,广泛应用于计算机科学和软件工程领域。下面是对初级数据结构二叉树的分析,包括基本概念、性质、操作和一些常见的二叉树类型。

一、基本概念
定义:二叉树(Binary Tree)是一种树形数据结构,其中每个节点最多有两个子节点,通常称为左子节点和右子节点。
节点:树中的每个元素称为节点(Node)。每个节点包含三部分:数据域(存储数据)、左指针(指向左子节点)和右指针(指向右子节点)。
根节点:没有父节点的节点称为根节点(Root Node)。
叶子节点:没有子节点的节点称为叶子节点(Leaf Node)。
深度(高度):从根节点到最远叶子节点的最长路径上的节点数(包括根节点和叶子节点)称为树的深度或高度。
二、基本性质
递归定义:二叉树可以通过递归方式定义,即二叉树要么为空,要么由根节点、左子树和右子树组成,其中左子树和右子树也是二叉树。
节点数目:对于深度为h的二叉树,最多有2^h - 1个节点(满二叉树情况下)。
遍历:二叉树的遍历是指按某种规则访问树中所有节点的过程。常见的遍历方式有前序遍历(Preorder)、中序遍历(Inorder)、后序遍历(Postorder)和层次遍历(Level Order)。
三、基本操作
1.创建二叉树:通过递归或迭代的方式创建二叉树。
2.插入节点:在二叉树中插入新节点,保持二叉树的性质(例如,在二叉搜索树中保持有序性)。
3.删除节点:从二叉树中删除某个节点,同时保持二叉树的性质。
4.查找节点:在二叉树中查找某个节点,通常用于二叉搜索树。
5.遍历二叉树:按照某种遍历方式访问树中的所有节点。
四、常见的二叉树类型
二叉搜索树(BST, Binary Search Tree):
性质:对于每个节点,左子树中的所有节点值小于该节点值,右子树中的所有节点值大于该节点值。
应用:用于高效查找、插入和删除操作。
平衡二叉树(AVL树、红黑树等):
性质:通过旋转等操作保持树的平衡,使得树的高度尽可能小,从而提高查找效率。
应用:用于需要频繁插入、删除和查找操作的场景。
表达式树:
性质:用于表示数学表达式的树形结构,其中每个节点表示运算符,叶子节点表示操作数。
应用:用于解析和计算表达式。
哈夫曼树(Huffman Tree):
性质:用于数据压缩的一种二叉树,根据字符出现的频率构建,频率高的字符靠近根节点。
**应用:**用于哈夫曼编码,实现无损数据压缩。
五、c++代码模版
#include<iostream>
using namespace std;
#define eType int;
template<typename T>
struct TreeNode {
T val;
TreeNode* left;
TreeNode* right;
TreeNode() :val(0), left(NULL), right(NULL) {}
TreeNode(T x):val(x),left(NULL),right(NULL){}
};
template<typename T>
class Tree {
TreeNode<T>* nodes;
TreeNode<T>* root;
size_t nodeSize;
TreeNode<T>* Create(T a[], int size, int nodeId, T nullNode);
void visit(TreeNode<T>* node);
void preOrder(TreeNode<T>* node);//前序遍历
void inOrder(TreeNode<T>* node);//中序遍历
void postOrder(TreeNode<T>* node);//后序遍历
void levelOrder(TreeNode<T>* node);//层序遍历
public:
Tree();
Tree(int maxSize);
~Tree();
TreeNode<T>* GetTreeNode(int id);
void CreateTree(T a[], int size, T nullNode);
void preOrderTraversal();
void inOrderTraversal();
void postOrderTraversal();
};
template<typename T>
Tree<T>::Tree() {
nodeSize = 100001;
nodes = new TreeNode<T>[nodeSize];
}
template<typename T>
Tree<T>::Tree(int maxSize) {
nodeSize = maxSize;
nodes = new TreeNode<T>[maxSize];
}
template<typename T>
Tree<T>::~Tree() {
delete[]nodes;
}
template<typename T>
TreeNode<T>* Tree<T>::GetTreeNode(int id) {
return &nodes[id];
}
template<typename T>
void Tree<T>::visit(TreeNode<T>* node) {
cout << node->val;
}
template<typename T>
void Tree<T>::CreateTree(T a[], int size, T nullNode) {
root = Create(a, size, 1, nullNode);
}
template<typename T>
TreeNode<T>* Tree<T>::Create(T a[], int size, int nodeId, T nullNode) {
if (nodeId >= size || a[nodeId] == nullNode) {
return NULL;
}
TreeNode<T>* nowNode = GetTreeNode(nodeId);
nowNode->val = a[nodeId];
nowNode->left = Create(a, size, nodeId * 2, nullNode);//每个节点的左子结点索引为它的两倍
nowNode->right = Create(a, size, nodeId * 2 + 1, nullNode);//右子节点为它的两倍加一
return nowNode;
}
template<typename T>
void Tree<T>::preOrder(TreeNode<T>* node) {
if (node) {
visit(node);
preOrder(node->left);
preOrder(node->right);
}
}
template<typename T>
void Tree<T>::inOrder(TreeNode<T>* node) {
if (node) {
inOrder(node->left);
visit(node);
inOrder(node->right);
}
}
template<typename T>
void Tree<T>::postOrder(TreeNode<T>* node) {
if (node) {
inOrder(node->left);
inOrder(node->right);
visit(node);
}
}
template<typename T>
void Tree<T>::preOrderTraversal() {
preOrder(root);
}
template<typename T>
void Tree<T>::inOrderTraversal() {
inOrder(root);
}
template<typename T>
void Tree<T>::postOrderTraversal() {
postOrder(root);
}
int main() {
const char nullNode = '-';
char a[15] = {
nullNode,'a','b','c','d',
nullNode,'e','f','g','h',
nullNode,nullNode,nullNode,nullNode,'i'
};
Tree<char>T(15);
T.CreateTree(a, 15, nullNode);
T.preOrderTraversal(); cout << endl;
T.inOrderTraversal(); cout << endl;
T.postOrderTraversal(); cout << endl;
return 0;
}
六、经典例题
1.——104. 二叉树的最大深度
(蓝色字体点进去看原题)
代码题解
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root==NULL)return 0;
int lmax=maxDepth(root->left);
int rmax=maxDepth(root->right);
return 1+max(lmax,rmax);
}
};
2.——LCR 175. 计算二叉树的深度
代码题解
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
int maxDepth;//用于记录最大深度
void dfs(TreeNode*root,int depth){
if(depth>maxDepth){
maxDepth=depth;
}
if(root){
dfs(root->left,depth+1);
dfs(root->right,depth+1);
}
}
public:
int calculateDepth(TreeNode* root) {
dfs(root,0);
return maxDepth;
}
};
3.——2331. 计算布尔二叉树的值
代码题解
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool evaluateTree(TreeNode* root) {
if(root==NULL)return false;
if(root->val==0||root->val==1){
return root->val==1;
}
if(root->val==2){
return evaluateTree(root->left)||evaluateTree(root->right);
}
return evaluateTree(root->left)&&evaluateTree(root->right);
}
};
七、总结
二叉树是一种非常灵活和强大的数据结构,通过不同的定义和操作,可以实现多种功能和应用。了解和掌握二叉树的基本概念、性质和操作,对于深入理解计算机科学和解决实际问题具有重要意义。

结语
相信大家通过本期学习初步了解二叉树,下期作品我会更新二叉树的十几道题库,我们下期一起学习二叉树的实战应用。

1304

被折叠的 条评论
为什么被折叠?



