C#二叉树

二叉树是一种常见的数据结构,它是由节点组成的一种树形结构,其中每个节点最多有两个子节点。二叉树的一个节点通常包含三部分:存储数据的变量、指向左子节点的指针和指向右子节点的指针。二叉树可以用于多种算法和操作,如搜索、排序和遍历。

在这里插入图片描述

二叉树遍历

遍历方式 顺序 C#递归实现核心代码

前序遍历 根 → 左 → 右 Console.Write(root.val); → 递归左 → 递归右

中序遍历 左 → 根 → 右 递归左 → Console.Write(root.val); → 递归右

后序遍历 左 → 右 → 根 递归左 → 递归右 → Console.Write(root.val);

二叉树的应用场景

快速查找与排序

二叉搜索树用于实现字典、数据库索引(如B树、B+树的基础)。

表达式树

编译器解析数学表达式时构建二叉树,叶节点为操作数,非叶节点为运算符。

哈夫曼编码

通过构建最优二叉树实现数据压缩。

决策树与机器学习

二叉树结构用于分类和回归模型的决策过程。

二叉树的优缺点

优点 缺点

逻辑清晰,易于实现递归操作 普通二叉树可能退化为链表(时间复杂度升至O(n))

二叉搜索树支持高效查找/插入 平衡二叉树实现复杂(如AVL树的旋转操作)

天然适合分治算法(如快速排序) 存储指针占用额外内存空间

实例1

using System;

using System.Collections.Generic;

public class TreeNode

{

public int val;

public TreeNode left;

public TreeNode right;

public TreeNode(int x) { val = x; }

}

class BinaryTreeDemo

{

static void Main()

{

// 构建二叉树

TreeNode root = new TreeNode(1)

{

left = new TreeNode(2)

{

left = new TreeNode(4),

right = new TreeNode(5)

},

right = new TreeNode(3)

};

Console.WriteLine("前序遍历:");

PreOrder(root); // 输出: 1 2 4 5 3

Console.WriteLine("\n层序遍历:");

LevelOrder(root); // 输出: 1 2 3 4 5

}

// 前序遍历

static void PreOrder(TreeNode root)

{

if (root == null) return;

Console.Write(root.val + " ");

PreOrder(root.left);

PreOrder(root.right);

}

// 层序遍历

static void LevelOrder(TreeNode root)

{

if (root == null) return;

Queue<TreeNode> queue = new Queue<TreeNode>();

queue.Enqueue(root);

while (queue.Count > 0)

{

TreeNode node = queue.Dequeue();

Console.Write(node.val + " ");

if (node.left != null) queue.Enqueue(node.left);

if (node.right != null) queue.Enqueue(node.right);

}

}

}

实例2

public class TreeNode<T>

{

public T Value { get; set; }

public TreeNode<T> Left { get; set; }

public TreeNode<T> Right { get; set; }

public TreeNode(T value)

{

Value = value;

Left = null;

Right = null;

}

}

public class BinaryTree<T>

{

public TreeNode<T> Root { get; private set; }

public BinaryTree()

{

Root = null;

}

// 插入新值到二叉树中

public void Add(T value)

{

if (Root == null)

{

Root = new TreeNode<T>(value);

}

else

{

AddTo(Root, value);

}

}

private void AddTo(TreeNode<T> node, T value)

{

if (Comparer<T>.Default.Compare(value, node.Value) < 0)

{

if (node.Left == null)

{

node.Left = new TreeNode<T>(value);

}

else

{

AddTo(node.Left, value);

}

}

else

{

if (node.Right == null)

{

node.Right = new TreeNode<T>(value);

}

else

{

AddTo(node.Right, value);

}

}

}

// 前序遍历(根-左-右)

public void PreOrderTraversal(TreeNode<T> node)

{

if (node != null)

{

Console.WriteLine(node.Value); // 访问节点

PreOrderTraversal(node.Left); // 遍历左子树

PreOrderTraversal(node.Right); // 遍历右子树

}

}

// 中序遍历(左-根-右)

public void InOrderTraversal(TreeNode<T> node)

{

if (node != null)

{

InOrderTraversal(node.Left); // 遍历左子树

Console.WriteLine(node.Value); // 访问节点

InOrderTraversal(node.Right); // 遍历右子树

}

}

// 后序遍历(左-右-根)

public void PostOrderTraversal(TreeNode<T> node)

{

if (node != null)

{

PostOrderTraversal(node.Left); // 遍历左子树

PostOrderTraversal(node.Right); // 遍历右子树

Console.WriteLine(node.Value); // 访问节点

}

}

}

实例3

class BSTDemo

{

static void Main()

{

TreeNode root = null;

// 插入节点

root = InsertBST(root, 5);

InsertBST(root, 3);

InsertBST(root, 7);

InsertBST(root, 2);

Console.WriteLine("中序遍历BST:");

InOrder(root); // 输出: 2 3 5 7

// 删除节点3

root = DeleteNode(root, 3);

Console.WriteLine("\n删除后:");

InOrder(root); // 输出: 2 5 7

}

// BST插入

static TreeNode InsertBST(TreeNode root, int val)

{

if (root == null) return new TreeNode(val);

if (val < root.val)

root.left = InsertBST(root.left, val);

else

root.right = InsertBST(root.right, val);

return root;

}

// BST删除(使用之前定义的DeleteNode方法)

// 中序遍历

static void InOrder(TreeNode root)

{

if (root == null) return;

InOrder(root.left);

Console.Write(root.val + " ");

InOrder(root.right);

}

}

实例4

class SymmetricTreeDemo

{

static void Main()

{

// 对称二叉树

TreeNode root1 = new TreeNode(1)

{

left = new TreeNode(2) { left = new TreeNode(3), right = new TreeNode(4) },

right = new TreeNode(2) { left = new TreeNode(4), right = new TreeNode(3) }

};

// 非对称二叉树

TreeNode root2 = new TreeNode(1)

{

left = new TreeNode(2) { right = new TreeNode(3) },

right = new TreeNode(2) { right = new TreeNode(3) }

};

Console.WriteLine("root1是否对称: " + IsSymmetric(root1)); // true

Console.WriteLine("root2是否对称: " + IsSymmetric(root2)); // false

}

static bool IsSymmetric(TreeNode root)

{

if (root == null) return true;

return CheckSymmetric(root.left, root.right);

}

static bool CheckSymmetric(TreeNode left, TreeNode right)

{

if (left == null && right == null) return true;

if (left == null || right == null) return false;

return left.val == right.val

&& CheckSymmetric(left.left, right.right)

&& CheckSymmetric(left.right, right.left);

}

}


实例5

class DepthDemo

{

static void Main()

{

TreeNode root = new TreeNode(1)

{

left = new TreeNode(2) { left = new TreeNode(4) },

right = new TreeNode(3)

};

Console.WriteLine("最大深度: " + MaxDepth(root)); // 输出: 3

}

static int MaxDepth(TreeNode root)

{

if (root == null) return 0;

return Math.Max(MaxDepth(root.left), MaxDepth(root.right)) + 1;

}

}

实例6

class PathSumDemo

{

static void Main()

{

TreeNode root = new TreeNode(5)

{

left = new TreeNode(4) { left = new TreeNode(11) { left = new TreeNode(7), right = new TreeNode(2) } },

right = new TreeNode(8) { left = new TreeNode(13), right = new TreeNode(4) { right = new TreeNode(1) } }

};

Console.WriteLine("是否存在和为22的路径: " + HasPathSum(root, 22)); // true

}

static bool HasPathSum(TreeNode root, int targetSum)

{

if (root == null) return false;

if (root.left == null && root.right == null)

return root.val == targetSum;

return HasPathSum(root.left, targetSum - root.val)

|| HasPathSum(root.right, targetSum - root.val);

}

}


关键点总结

递归思想:二叉树问题多通过递归解决,注意终止条件(root == null)

BST特性:插入/删除时利用左小右大规则

遍历选择:

前序:根节点最先访问

中序:BST会得到有序序列

层序:需要队列辅助

空间复杂度:

递归:O(h)(h为树高)

层序:O(n)

原文链接:,转发请注明来源!