
树(Tree)是一种非线性的数据结构,它是由 n(n ≥ 0)个有限节点组成的集合。如果 n = 0,称为空树;如果 n > 0,则:
二叉树(Binary Tree)是一种特殊的树,每个节点最多有两个子树,分别称为左子树和右子树。二叉树的子树有左右之分,且不能交换。
二叉树的基本操作包括:
二叉树的存储结构主要有两种:
以下是一个简单的二叉树结构图解:
A
/ \
B C
/ \ /
D E F遍历是指按照某种顺序访问二叉树中的每个节点,且每个节点只访问一次。常见的遍历方法有:
遍历算法可以应用于:
递归遍历可以转换为基于栈的非递归遍历,以避免递归带来的栈溢出问题。
线索二叉树是在二叉树的链式存储中,利用空指针域存储节点的前驱和后继信息,以提高遍历效率。
通过前序和中序遍历序列,或者后序和中序遍历序列,可以唯一确定一棵二叉树。
以下是一个二叉树的前序遍历图解:
前序遍历:A → B → D → E → C → F
树的存储结构主要有:
哈夫曼树(Huffman Tree)是一种带权路径长度最小的二叉树,也称为最优二叉树。构造哈夫曼树的算法如下:
哈夫曼编码是一种基于哈夫曼树的编码方法,左子树表示0,右子树表示1。每个叶子节点的编码是从根节点到该叶子节点路径上的0和1组成的字符串。
以下是一个哈夫曼树的构造过程图解:
初始权值:1, 2, 3, 4
步骤1:选择1和2,构造新树,权值为3
步骤2:选择3和3,构造新树,权值为6
步骤3:选择4和6,构造新树,权值为10
最终哈夫曼树:
10
/ \
4 6
/ \
3 3
/ \ / \
1 2 ... ...数据结构 | 查找 | 插入 | 删除 |
|---|---|---|---|
二叉树 | O(n) | O(n) | O(n) |
平衡二叉树 | O(log n) | O(log n) | O(log n) |
数据结构 | 空间复杂度 |
|---|---|
二叉树 | O(n) |
数据结构 | 适用场景 |
|---|---|
二叉树 | 表达式求值、查找算法等 |
哈夫曼树 | 数据压缩、编码等 |
#include <stdio.h>
#include <stdlib.h>
// 定义二叉树节点
typedef struct TreeNode {
char data;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
// 创建新节点
TreeNode* createNode(char data) {
TreeNode *newNode = (TreeNode*)malloc(sizeof(TreeNode));
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// 前序遍历
void preOrder(TreeNode *root) {
if (root != NULL) {
printf("%c ", root->data); // 访问根节点
preOrder(root->left); // 递归遍历左子树
preOrder(root->right); // 递归遍历右子树
}
}
// 中序遍历
void inOrder(TreeNode *root) {
if (root != NULL) {
inOrder(root->left); // 递归遍历左子树
printf("%c ", root->data); // 访问根节点
inOrder(root->right); // 递归遍历右子树
}
}
// 后序遍历
void postOrder(TreeNode *root) {
if (root != NULL) {
postOrder(root->left); // 递归遍历左子树
postOrder(root->right); // 递归遍历右子树
printf("%c ", root->data); // 访问根节点
}
}
int main() {
// 创建二叉树
TreeNode *root = createNode('A');
root->left = createNode('B');
root->right = createNode('C');
root->left->left = createNode('D');
root->left->right = createNode('E');
root->right->left = createNode('F');
// 遍历二叉树
printf("前序遍历: ");
preOrder(root);
printf("\n");
printf("中序遍历: ");
inOrder(root);
printf("\n");
printf("后序遍历: ");
postOrder(root);
printf("\n");
return 0;
}
#include <iostream>
using namespace std;
// 定义二叉树节点
struct TreeNode {
char data;
TreeNode *left;
TreeNode *right;
TreeNode(char val) : data(val), left(nullptr), right(nullptr) {}
};
// 前序遍历
void preOrder(TreeNode *root) {
if (root != nullptr) {
cout << root->data << " "; // 访问根节点
preOrder(root->left); // 递归遍历左子树
preOrder(root->right); // 递归遍历右子树
}
}
// 中序遍历
void inOrder(TreeNode *root) {
if (root != nullptr) {
inOrder(root->left); // 递归遍历左子树
cout << root->data << " "; // 访问根节点
inOrder(root->right); // 递归遍历右子树
}
}
// 后序遍历
void postOrder(TreeNode *root) {
if (root != nullptr) {
postOrder(root->left); // 递归遍历左子树
postOrder(root->right); // 递归遍历右子树
cout << root->data << " "; // 访问根节点
}
}
int main() {
// 创建二叉树
TreeNode *root = new TreeNode('A');
root->left = new TreeNode('B');
root->right = new TreeNode('C');
root->left->left = new TreeNode('D');
root->left->right = new TreeNode('E');
root->right->left = new TreeNode('F');
// 遍历二叉树
cout << "前序遍历: ";
preOrder(root);
cout << endl;
cout << "中序遍历: ";
inOrder(root);
cout << endl;
cout << "后序遍历: ";
postOrder(root);
cout << endl;
return 0;
}
public class BinaryTree {
// 定义二叉树节点
static class TreeNode {
char data;
TreeNode left;
TreeNode right;
TreeNode(char data) {
this.data = data;
left = null;
right = null;
}
}
// 前序遍历
void preOrder(TreeNode root) {
if (root != null) {
System.out.print(root.data + " "); // 访问根节点
preOrder(root.left); // 递归遍历左子树
preOrder(root.right); // 递归遍历右子树
}
}
// 中序遍历
void inOrder(TreeNode root) {
if (root != null) {
inOrder(root.left); // 递归遍历左子树
System.out.print(root.data + " "); // 访问根节点
inOrder(root.right); // 递归遍历右子树
}
}
// 后序遍历
void postOrder(TreeNode root) {
if (root != null) {
postOrder(root.left); // 递归遍历左子树
postOrder(root.right); // 递归遍历右子树
System.out.print(root.data + " "); // 访问根节点
}
}
public static void main(String[] args) {
BinaryTree tree = new BinaryTree();
TreeNode root = new TreeNode('A');
root.left = new TreeNode('B');
root.right = new TreeNode('C');
root.left.left = new TreeNode('D');
root.left.right = new TreeNode('E');
root.right.left = new TreeNode('F');
System.out.print("前序遍历: ");
tree.preOrder(root);
System.out.println();
System.out.print("中序遍历: ");
tree.inOrder(root);
System.out.println();
System.out.print("后序遍历: ");
tree.postOrder(root);
System.out.println();
}
}
class TreeNode:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# 前序遍历
def pre_order(root):
if root is not None:
print(root.data, end=" ") # 访问根节点
pre_order(root.left) # 递归遍历左子树
pre_order(root.right) # 递归遍历右子树
# 中序遍历
def in_order(root):
if root is not None:
in_order(root.left) # 递归遍历左子树
print(root.data, end=" ") # 访问根节点
in_order(root.right) # 递归遍历右子树
# 后序遍历
def post_order(root):
if root is not None:
post_order(root.left) # 递归遍历左子树
post_order(root.right) # 递归遍历右子树
print(root.data, end=" ") # 访问根节点
if __name__ == "__main__":
# 创建二叉树
root = TreeNode('A')
root.left = TreeNode('B')
root.right = TreeNode('C')
root.left.left = TreeNode('D')
root.left.right = TreeNode('E')
root.right.left = TreeNode('F')
# 遍历二叉树
print("前序遍历:", end=" ")
pre_order(root)
print()
print("中序遍历:", end=" ")
in_order(root)
print()
print("后序遍历:", end=" ")
post_order(root)
print()
通过以上内容,我们详细讲解了树和二叉树的定义、性质、存储结构、遍历方法以及哈夫曼树的应用。希望这些内容能够帮助你更好地理解和使用树和二叉树这种数据结构。每种数据结构的代码实现都附有详细的注释,便于读者理解和动手操作。