Skip to content

Commit 2af77ff

Browse files
authored
feat(csharp): add csharp code for array binary tree (#632)
1 parent 2b7d7aa commit 2af77ff

File tree

3 files changed

+184
-37
lines changed

3 files changed

+184
-37
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/**
2+
* File: array_binary_tree.cs
3+
* Created Time: 2023-07-20
4+
* Author: hpstory ([email protected])
5+
*/
6+
7+
namespace hello_algo.chapter_tree;
8+
9+
/* 数组表示下的二叉树类 */
10+
public class ArrayBinaryTree {
11+
private List<int?> tree;
12+
13+
/* 构造方法 */
14+
public ArrayBinaryTree(List<int?> arr) {
15+
tree = new List<int?>(arr);
16+
}
17+
18+
/* 节点数量 */
19+
public int size() {
20+
return tree.Count;
21+
}
22+
23+
/* 获取索引为 i 节点的值 */
24+
public int? val(int i) {
25+
// 若索引越界,则返回 null ,代表空位
26+
if (i < 0 || i >= size())
27+
return null;
28+
return tree[i];
29+
}
30+
31+
/* 获取索引为 i 节点的左子节点的索引 */
32+
public int left(int i) {
33+
return 2 * i + 1;
34+
}
35+
36+
/* 获取索引为 i 节点的右子节点的索引 */
37+
public int right(int i) {
38+
return 2 * i + 2;
39+
}
40+
41+
/* 获取索引为 i 节点的父节点的索引 */
42+
public int parent(int i) {
43+
return (i - 1) / 2;
44+
}
45+
46+
/* 层序遍历 */
47+
public List<int> levelOrder() {
48+
List<int> res = new List<int>();
49+
// 直接遍历数组
50+
for (int i = 0; i < size(); i++) {
51+
if (val(i).HasValue)
52+
res.Add(val(i).Value);
53+
}
54+
return res;
55+
}
56+
57+
/* 深度优先遍历 */
58+
private void dfs(int i, string order, List<int> res) {
59+
// 若为空位,则返回
60+
if (!val(i).HasValue)
61+
return;
62+
// 前序遍历
63+
if (order == "pre")
64+
res.Add(val(i).Value);
65+
dfs(left(i), order, res);
66+
// 中序遍历
67+
if (order == "in")
68+
res.Add(val(i).Value);
69+
dfs(right(i), order, res);
70+
// 后序遍历
71+
if (order == "post")
72+
res.Add(val(i).Value);
73+
}
74+
75+
/* 前序遍历 */
76+
public List<int> preOrder() {
77+
List<int> res = new List<int>();
78+
dfs(0, "pre", res);
79+
return res;
80+
}
81+
82+
/* 中序遍历 */
83+
public List<int> inOrder() {
84+
List<int> res = new List<int>();
85+
dfs(0, "in", res);
86+
return res;
87+
}
88+
89+
/* 后序遍历 */
90+
public List<int> postOrder() {
91+
List<int> res = new List<int>();
92+
dfs(0, "post", res);
93+
return res;
94+
}
95+
}
96+
97+
public class array_binary_tree {
98+
[Test]
99+
public void Test() {
100+
// 初始化二叉树
101+
// 这里借助了一个从数组直接生成二叉树的函数
102+
List<int?> arr = new List<int?> { 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 };
103+
104+
TreeNode root = TreeNode.ListToTree(arr);
105+
Console.WriteLine("\n初始化二叉树\n");
106+
Console.WriteLine("二叉树的数组表示:");
107+
Console.WriteLine(arr.PrintList());
108+
Console.WriteLine("二叉树的链表表示:");
109+
PrintUtil.PrintTree(root);
110+
111+
// 数组表示下的二叉树类
112+
ArrayBinaryTree abt = new ArrayBinaryTree(arr);
113+
114+
// 访问节点
115+
int i = 1;
116+
int l = abt.left(i);
117+
int r = abt.right(i);
118+
int p = abt.parent(i);
119+
Console.WriteLine("\n当前节点的索引为 " + i + " ,值为 " + abt.val(i));
120+
Console.WriteLine("其左子节点的索引为 " + l + " ,值为 " + (abt.val(l).HasValue ? abt.val(l) : "null"));
121+
Console.WriteLine("其右子节点的索引为 " + r + " ,值为 " + (abt.val(r).HasValue ? abt.val(r) : "null"));
122+
Console.WriteLine("其父节点的索引为 " + p + " ,值为 " + (abt.val(p).HasValue ? abt.val(p) : "null"));
123+
124+
// 遍历树
125+
List<int> res = abt.levelOrder();
126+
Console.WriteLine("\n层序遍历为:" + res.PrintList());
127+
res = abt.preOrder();
128+
Console.WriteLine("前序遍历为:" + res.PrintList());
129+
res = abt.inOrder();
130+
Console.WriteLine("中序遍历为:" + res.PrintList());
131+
res = abt.postOrder();
132+
Console.WriteLine("后序遍历为:" + res.PrintList());
133+
}
134+
}

codes/csharp/utils/PrintUtil.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@ public Trunk(Trunk? prev, string str) {
1616
}
1717
};
1818

19-
public class PrintUtil {
19+
public static class PrintUtil {
2020
/* Print a list */
2121
public static void PrintList<T>(IList<T> list) {
2222
Console.WriteLine("[" + string.Join(", ", list) + "]");
2323
}
2424

25+
public static string PrintList<T>(this IEnumerable<T?> list) {
26+
return $"[ {string.Join(", ", list.Select(x => x?.ToString() ?? "null"))} ]";
27+
}
28+
2529
/* Print a matrix (Array) */
2630
public static void PrintMatrix<T>(T[][] matrix) {
2731
Console.WriteLine("[");
@@ -131,4 +135,4 @@ public static void PrintHeap(PriorityQueue<int, int> queue) {
131135
TreeNode tree = TreeNode.ListToTree(list.Cast<int?>().ToList());
132136
PrintTree(tree);
133137
}
134-
}
138+
}

codes/csharp/utils/TreeNode.cs

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,50 +13,59 @@ public class TreeNode {
1313
public TreeNode? left; // 左子节点引用
1414
public TreeNode? right; // 右子节点引用
1515

16+
/* 构造方法 */
1617
public TreeNode(int x) {
1718
val = x;
1819
}
1920

20-
/* Generate a binary tree given an array */
21-
public static TreeNode? ListToTree(List<int?> arr) {
22-
if (arr.Count == 0 || arr[0] == null)
23-
return null;
21+
// 序列化编码规则请参考:
22+
// https://www.hello-algo.com/chapter_tree/array_representation_of_tree/
23+
// 二叉树的数组表示:
24+
// [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15]
25+
// 二叉树的链表表示:
26+
// /——— 15
27+
// /——— 7
28+
// /——— 3
29+
// | \——— 6
30+
// | \——— 12
31+
// ——— 1
32+
// \——— 2
33+
// | /——— 9
34+
// \——— 4
35+
// \——— 8
2436

25-
TreeNode root = new TreeNode(arr[0]!.Value);
26-
Queue<TreeNode> queue = new Queue<TreeNode>();
27-
queue.Enqueue(root);
28-
int i = 0;
29-
while (queue.Count != 0) {
30-
TreeNode node = queue.Dequeue();
31-
if (++i >= arr.Count) break;
32-
if (arr[i] != null) {
33-
node.left = new TreeNode((int)arr[i]);
34-
queue.Enqueue(node.left);
35-
}
36-
if (++i >= arr.Count) break;
37-
if (arr[i] != null) {
38-
node.right = new TreeNode((int)arr[i]);
39-
queue.Enqueue(node.right);
40-
}
37+
/* 将列表反序列化为二叉树:递归 */
38+
private static TreeNode? ListToTreeDFS(List<int?> arr, int i) {
39+
if (i < 0|| i >= arr.Count || !arr[i].HasValue) {
40+
return null;
4141
}
42+
TreeNode root = new TreeNode(arr[i].Value);
43+
root.left = ListToTreeDFS(arr, 2 * i + 1);
44+
root.right = ListToTreeDFS(arr, 2 * i + 2);
4245
return root;
4346
}
4447

45-
/* Serialize a binary tree to a list */
46-
public static List<int?> TreeToList(TreeNode root) {
47-
List<int?> list = new();
48-
if (root == null) return list;
49-
Queue<TreeNode?> queue = new();
50-
while (queue.Count != 0) {
51-
TreeNode? node = queue.Dequeue();
52-
if (node != null) {
53-
list.Add(node.val);
54-
queue.Enqueue(node.left);
55-
queue.Enqueue(node.right);
56-
} else {
57-
list.Add(null);
58-
}
48+
/* 将列表反序列化为二叉树 */
49+
public static TreeNode? ListToTree(List<int?> arr) {
50+
return ListToTreeDFS(arr, 0);
51+
}
52+
53+
/* 将二叉树序列化为列表:递归 */
54+
private static void TreeToListDFS(TreeNode? root, int i, List<int?> res) {
55+
if (root == null)
56+
return;
57+
while (i >= res.Count) {
58+
res.Add(null);
5959
}
60-
return list;
60+
res[i] = root.val;
61+
TreeToListDFS(root.left, 2 * i + 1, res);
62+
TreeToListDFS(root.right, 2 * i + 2, res);
63+
}
64+
65+
/* 将二叉树序列化为列表 */
66+
public static List<int?> treeToList(TreeNode root) {
67+
List<int?> res = new List<int?>();
68+
TreeToListDFS(root, 0, res);
69+
return res;
6170
}
6271
}

0 commit comments

Comments
 (0)