R Program to Implement Tree Sort

R Program to Implement Tree Sort

Tree Sort is a fascinating sorting algorithm that uses a binary search tree (BST) to organize data in a way that makes sorting straightforward and efficient. Instead of comparing every element repeatedly, Tree Sort inserts each element into a BST, and an in-order traversal of the tree naturally produces a sorted sequence. This approach combines the ideas of data structures and sorting, which makes it an excellent learning tool for beginners in R programming.

Tree Sort is particularly useful when you want to maintain a dynamic dataset, where elements are frequently added or removed, because the BST can handle insertions efficiently while keeping the data in order. Although not always the fastest compared to algorithms like Quick Sort for random datasets, Tree Sort is stable and easy to understand conceptually. For learners, implementing Tree Sort in R provides an opportunity to see how recursion, trees, and traversal techniques work together to solve a real problem.

Program 1: Basic Tree Sort using Binary Search Tree

This program demonstrates a straightforward Tree Sort using a binary search tree. It is simple and ideal for beginners to understand the core concept.

insert_node <- function(root, value) {

  if (is.null(root)) {
    return(list(value = value, left = NULL, right = NULL))
  }

  if (value <= root$value) {
    root$left <- insert_node(root$left, value)
  } else {
    root$right <- insert_node(root$right, value)
  }

  return(root)

}

in_order_traversal <- function(root, result = c()) {

  if (!is.null(root$left)) {
    result <- in_order_traversal(root$left, result)
  }

  result <- c(result, root$value)

  if (!is.null(root$right)) {
    result <- in_order_traversal(root$right, result)
  }

  return(result)

}

tree_sort <- function(arr) {

  root <- NULL

  for (value in arr) {
    root <- insert_node(root, value)
  }

  return(in_order_traversal(root))

}

data <- c(5, 3, 8, 1, 4, 7)
print(tree_sort(data))

In this program, we first create a BST by inserting each element one by one. Then, an in-order traversal visits nodes in sorted order. Beginners can see how Tree Sort relies on the structure of the tree rather than repeated comparisons.

Program 2: Tree Sort with recursive insertion and traversal

This version emphasizes recursion in both insertion and traversal, helping beginners understand how recursive calls work in tree algorithms.

insert_node_recursive <- function(root, value) {

  if (is.null(root)) {
    return(list(value = value, left = NULL, right = NULL))
  }

  if (value <= root$value) {
    root$left <- insert_node_recursive(root$left, value)
  } else {
    root$right <- insert_node_recursive(root$right, value)
  }

  return(root)

}

in_order_recursive <- function(root) {

  if (is.null(root)) return(c())

  c(in_order_recursive(root$left), root$value, in_order_recursive(root$right))

}

tree_sort_recursive <- function(arr) {

  root <- NULL

  for (val in arr) {
    root <- insert_node_recursive(root, val)
  }

  in_order_recursive(root)

}

data <- c(10, 2, 5, 3, 7)
print(tree_sort_recursive(data))

This version highlights the elegance of recursion, which is a core concept in many tree algorithms. Beginners can see how the tree’s recursive structure makes sorting natural and easy to follow.

Program 3: Tree Sort with input validation

This example adds a check to ensure that the input is numeric, which is a good habit for robust R programming.

insert_node <- function(root, value) {

  if (is.null(root)) {
    return(list(value = value, left = NULL, right = NULL))
  }

  if (value <= root$value) {
    root$left <- insert_node(root$left, value)
  } else {
    root$right <- insert_node(root$right, value)
  }

  return(root)

}

in_order_traversal <- function(root, result = c()) {

  if (!is.null(root$left)) {
    result <- in_order_traversal(root$left, result)
  }

  result <- c(result, root$value)

  if (!is.null(root$right)) {
    result <- in_order_traversal(root$right, result)
  }

  return(result)

}

tree_sort <- function(arr) {

  root <- NULL

  for (value in arr) {
    root <- insert_node(root, value)
  }

  return(in_order_traversal(root))

}


tree_sort_safe <- function(arr) {

  if (!is.numeric(arr)) {
    stop("Input must be numeric")
  }

  tree_sort(arr)

}

data <- c(9, 4, 6, 1, 7)
print(tree_sort_safe(data))

Input validation teaches beginners to write code that handles errors gracefully, making programs more reliable in practice.

Program 4: Tree Sort with detailed printout

This version prints the tree at each insertion to help learners visualize how elements are arranged.

insert_node_verbose <- function(root, value) {

  if (is.null(root)) {

    print(paste("Inserting", value, "at root"))
    return(list(value = value, left = NULL, right = NULL))

  }

  if (value <= root$value) {

    print(paste("Inserting", value, "to left of", root$value))
    root$left <- insert_node_verbose(root$left, value)

  } else {

    print(paste("Inserting", value, "to right of", root$value))
    root$right <- insert_node_verbose(root$right, value)

  }

  return(root)

}

in_order_traversal <- function(root, result = c()) {

  if (!is.null(root$left)) {
    result <- in_order_traversal(root$left, result)
  }

  result <- c(result, root$value)

  if (!is.null(root$right)) {
    result <- in_order_traversal(root$right, result)
  }

  return(result)

}

tree_sort_verbose <- function(arr) {

  root <- NULL

  for (value in arr) {
    root <- insert_node_verbose(root, value)
  }

  in_order_traversal(root)

}

data <- c(6, 2, 8, 4)
print(tree_sort_verbose(data))

Beginners can now follow how each number finds its place in the tree. Seeing the tree grow helps understand why in-order traversal produces a sorted array.

Program 5: Tree Sort using while loop simulation

This version demonstrates a different approach by simulating traversal using a loop-like structure for beginners practicing loops.

insert_node <- function(root, value) {

  if (is.null(root)) {
    return(list(value = value, left = NULL, right = NULL))
  }

  if (value <= root$value) {
    root$left <- insert_node(root$left, value)
  } else {
    root$right <- insert_node(root$right, value)
  }

  return(root)

}

tree_sort_loop <- function(arr) {

  root <- NULL

  for (v in arr) {
    root <- insert_node(root, v)
  }

  stack <- list()
  result <- c()
  current <- root

  while (!is.null(current) || length(stack) > 0) {

    while (!is.null(current)) {
      stack <- c(list(current), stack)
      current <- current$left
    }

    current <- stack[[1]]
    stack <- stack[-1]
    result <- c(result, current$value)
    current <- current$right

  }

  return(result)

}

data <- c(3, 1, 4, 2, 5)

print(tree_sort_loop(data))

Using a stack mimics the recursion manually. Beginners can compare this with the recursive version to see how recursion and iteration can achieve the same result.

Program 6: Tree Sort for nearly sorted data

Tree Sort handles nearly sorted data efficiently, and this program demonstrates that property.

insert_node <- function(root, value) {

  if (is.null(root)) {
    return(list(value = value, left = NULL, right = NULL))
  }

  if (value <= root$value) {
    root$left <- insert_node(root$left, value)
  } else {
    root$right <- insert_node(root$right, value)
  }

  return(root)

}

in_order_traversal <- function(root, result = c()) {

  if (!is.null(root$left)) {
    result <- in_order_traversal(root$left, result)
  }

  result <- c(result, root$value)

  if (!is.null(root$right)) {
    result <- in_order_traversal(root$right, result)
  }

  return(result)

}

tree_sort <- function(arr) {

  root <- NULL

  for (value in arr) {
    root <- insert_node(root, value)
  }

  return(in_order_traversal(root))

}

data <- c(1, 2, 3, 5, 4, 6)
print(tree_sort(data))

In nearly sorted datasets, Tree Sort constructs a balanced tree naturally, resulting in efficient sorting without unnecessary comparisons.

Program 7: Tree Sort with repeated numbers

Tree Sort can handle duplicates effectively. This program shows how duplicates are inserted to the left subtree by design.

insert_node <- function(root, value) {

  if (is.null(root)) {
    return(list(value = value, left = NULL, right = NULL))
  }

  if (value <= root$value) {
    root$left <- insert_node(root$left, value)
  } else {
    root$right <- insert_node(root$right, value)
  }

  return(root)

}

in_order_traversal <- function(root, result = c()) {

  if (!is.null(root$left)) {
    result <- in_order_traversal(root$left, result)
  }

  result <- c(result, root$value)

  if (!is.null(root$right)) {
    result <- in_order_traversal(root$right, result)
  }

  return(result)

}

tree_sort <- function(arr) {

  root <- NULL

  for (value in arr) {
    root <- insert_node(root, value)
  }

  return(in_order_traversal(root))

}

data <- c(4, 2, 4, 3, 2)
print(tree_sort(data))

Beginners can see that duplicates maintain stability in Tree Sort, preserving relative order of equal elements.

Program 8: Tree Sort for larger datasets

This version shows Tree Sort on a larger predefined dataset to demonstrate its scalability.

insert_node <- function(root, value) {

  if (is.null(root)) {
    return(list(value = value, left = NULL, right = NULL))
  }

  if (value <= root$value) {
    root$left <- insert_node(root$left, value)
  } else {
    root$right <- insert_node(root$right, value)
  }

  return(root)

}

in_order_traversal <- function(root, result = c()) {

  if (!is.null(root$left)) {
    result <- in_order_traversal(root$left, result)
  }

  result <- c(result, root$value)

  if (!is.null(root$right)) {
    result <- in_order_traversal(root$right, result)
  }

  return(result)

}

tree_sort <- function(arr) {

  root <- NULL

  for (value in arr) {
    root <- insert_node(root, value)
  }

  return(in_order_traversal(root))

}

data <- c(12, 7, 5, 3, 10, 6, 8, 2)
print(tree_sort(data))

Seeing the algorithm handle more elements helps beginners trust the approach and understand its performance characteristics.

Program 9: Tree Sort with negative and floating-point numbers

Tree Sort can sort negative numbers and decimals without modification. This program demonstrates it clearly.

insert_node <- function(root, value) {

  if (is.null(root)) {
    return(list(value = value, left = NULL, right = NULL))
  }

  if (value <= root$value) {
    root$left <- insert_node(root$left, value)
  } else {
    root$right <- insert_node(root$right, value)
  }

  return(root)

}

in_order_traversal <- function(root, result = c()) {

  if (!is.null(root$left)) {
    result <- in_order_traversal(root$left, result)
  }

  result <- c(result, root$value)

  if (!is.null(root$right)) {
    result <- in_order_traversal(root$right, result)
  }

  return(result)

}

tree_sort <- function(arr) {

  root <- NULL

  for (value in arr) {
    root <- insert_node(root, value)
  }

  return(in_order_traversal(root))

}

data <- c(-5, 2.5, 0, -1, 3)
print(tree_sort(data))

This shows that Tree Sort is versatile and works naturally with a wide range of numeric inputs, making it suitable for real-world applications.

Frequently Asked Questions (FAQ)

This section answers common beginner questions about Tree Sort in R.

Q1. Why use Tree Sort over other algorithms?
Tree Sort is intuitive, uses binary trees, and works efficiently for dynamic datasets or nearly sorted data.

Q2. Does Tree Sort handle duplicates?
Yes, duplicates can be inserted into the left subtree or right depending on implementation, maintaining stability.

Q3. Is Tree Sort recursive or iterative?
It can be implemented both ways. Recursion is simpler to write, while iteration using a stack simulates recursion.

Q4. Can Tree Sort handle negative and decimal numbers?
Yes, unlike Counting Sort, Tree Sort handles any numeric value without special adjustments.

Conclusion

Tree Sort is an elegant algorithm that combines the power of binary search trees with sorting. By practicing Tree Sort in R, beginners learn important programming concepts such as recursion, tree structures, and in-order traversal.

Exploring different versions—from recursive to iterative, from verbose to safe input—helps beginners build confidence and flexibility in programming. Keep experimenting with different datasets and variations to understand Tree Sort deeply and enjoy how data structures can make sorting intuitive and efficient.

Scroll to Top