public static void Main()
var values = new int[]{1, 5, 2, 3, 6, 4, 7, 12, 3, 5, 55, 12, 30, 22, 10, 11, 25, 36 };
var bst = new BinaryTree();
foreach(var num in values){
Console.WriteLine("Chiều cao của cây: {0}", bst.GetTreeDepth(bst.Root));
Console.Write("In cây theo giá trị tăng: ");
bst.TraverseInOrder(bst.Root);
Console.Write("In cây không sắp xếp: ");
bst.TraversePreorder(bst.Root);
Console.Write("In cây theo giá trị giảm: ");
bst.TraversePostOrder(bst.Root);
Console.WriteLine("!!!Nâng cao!!!");
Console.Write("In cây theo giá trị tăng: ".PadRight(26, ' '));
bst.TraverseInOrderExp(bst.Root, (node) => {
var padded = node.Value.ToString().PadLeft(2).PadRight(3);
Console.Write("| {0} ", padded);
Console.Write("In cây không sắp xếp: ".PadRight(26, ' '));
bst.TraversePreorderExp(bst.Root, (node) => {
var padded = node.Value.ToString().PadLeft(2).PadRight(3);
Console.Write("| {0} ", padded);
Console.Write("In cây theo giá trị giảm: ".PadRight(26, ' '));
bst.TraversePostOrderExp(bst.Root, (node) => {
var padded = node.Value.ToString().PadLeft(2).PadRight(3);
Console.Write("| {0} ", padded);
var node1 = bst.Find(bst.Root, x1);
Console.WriteLine("Tìm giá trị: {0}, {1}", x1, node1 == null ? "Không tìm thấy" : "Tìm thấy giá trị " + node1.Value);
public int Value { get; set; }
public Node Left { get; set; }
public Node Right { get; set; }
public class BinaryTree {
public Node Root { get; private set; }
public BinaryTree(Node root){
public BinaryTree Insert(int val){
var newNode = new Node(val);
parentNode = currentNode;
if(val < currentNode.Value){
if(currentNode.Left == null){
currentNode.Left = newNode;
currentNode = currentNode.Left;
if(currentNode.Right == null){
currentNode.Right = newNode;
currentNode = currentNode.Right;
public void TraversePreorder(Node node){
Console.Write("{0} ", node.Value);
TraversePreorder(node.Left);
TraversePreorder(node.Right);
public void TraverseInOrder(Node node){
TraverseInOrder(node.Left);
Console.Write("{0} ", node.Value);
TraverseInOrder(node.Right);
public void TraversePostOrder(Node node){
TraversePostOrder(node.Right);
Console.Write("{0} ", node.Value);
TraversePostOrder(node.Left);
public void TraversePreorderExp(Node node, Action<Node> expression){
TraversePreorderExp(node.Left, expression);
TraversePreorderExp(node.Right, expression);
public void TraverseInOrderExp(Node node, Action<Node> expression){
TraverseInOrderExp(node.Left, expression);
TraverseInOrderExp(node.Right, expression);
public void TraversePostOrderExp(Node node, Action<Node> expression){
TraversePostOrderExp(node.Right, expression);
TraversePostOrderExp(node.Left, expression);
public Node Find(Node node, int val){
} else if (node.Value > val){
return Find(node.Left, val);
return Find(node.Right, val);
public int GetTreeDepth(){
return GetTreeDepth(this.Root);
public int GetTreeDepth(Node node){
return node == null ? 0 : Math.Max(GetTreeDepth(node.Left), GetTreeDepth(node.Right)) + 1;