k-ary Tree in Data Structure



What is K-Ary Tree?

K-ary tree also known as K-way or N-ary tree is a tree data structure in which each node has at most K children. The value of K is fixed for a given tree. The value of K can be 2, 3, 4, 5, etc.

For example, a binary tree is a 2-ary tree, a ternary tree is a 3-ary tree, and so on.

Characteristics of K-Ary Tree

Following are the characteristics of K-ary tree:

  • K : This number represents the maximum number of children a node can have.
  • Height : The height of a K-ary tree is the maximum number of edges on the longest path between the root node and a leaf node.
  • Level: The level of a node is the number of edges on the path from the root node to the node.
  • Root: The topmost node in the tree.
  • Parent: The node that is connected to its child node.
  • Leaf Node: The node that does not have any children.
  • Internal Node: The node that has at least one child.

Types of K-Ary Tree

There are two types of K-ary tree:

  • Full K-ary Tree : A K-ary tree is called a full K-ary tree if each node has exactly K children or no children.
  • Complete K-ary Tree : A K-ary tree is called a complete K-ary tree if all levels are completely filled except possibly for the last level, which is filled from left to right.

Representation of K-Ary Tree

K-ary tree can be represented using an array. The array representation of a complete K-ary tree is as follows:

  • Parent Node : The parent node of the ith node is at the position (i-1)/K.
  • Child Node : The K children of the ith node are at the positions K*i+1, K*i+2, ..., K*i+K.

For example, consider a 3-ary tree:

3-ary Tree

The array representation of the above 3-ary tree is as follows:

The formula to find the parent node of the ith node is (i-1)/3.

The formula to find the child nodes of the ith node is 3*i+1, 3*i+2, 3*i+3.

Array: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

Parent Node:
Parent of 2: (2-1)/3 = 0
Parent of 3: (3-1)/3 = 0
Parent of 4: (4-1)/3 = 1
Parent of 5: (5-1)/3 = 1
Parent of 6: (6-1)/3 = 1
Parent of 7: (7-1)/3 = 2
Parent of 8: (8-1)/3 = 2
Parent of 9: (9-1)/3 = 2
Parent of 10: (10-1)/3 = 3
Parent of 11: (11-1)/3 = 3
Parent of 12: (12-1)/3 = 3
Parent of 13: (13-1)/3 = 4
Parent of 14: (14-1)/3 = 4
Parent of 15: (15-1)/3 = 4

Similarly, we can find the child nodes of each node using the above formula.

Operations on K-Ary Tree

Following are the important operations that can be performed on a K-ary tree:

  • Insertion: Insert a new node into the K-ary tree.
  • Deletion: Delete a node from the K-ary tree.
  • Traversal: Traverse the K-ary tree in different ways such as inorder, preorder, postorder, and level order.
  • Search: Search for a specific node in the K-ary tree.

Implementation of K-Ary Tree

We will discuss the Insertion operation on the K-ary tree. The following is the algorithm to insert a new node into the K-ary tree

Algorithm to Insert a Node in K-Ary Tree

Follow the steps below to insert a new node into the K-ary tree:

1. Create a class Node with data and an array of children.
2. Create a class KaryTree with a root node and a K-ary tree.
3. Insert a new node into the K-ary tree.

Code to Insert a Node in K-Ary Tree

Following is the code to insert a new node into the K-ary tree:

#include <stdio.h>
#include <stdlib.h>

#define MAX_CHILDREN 3  // Define k (max number of children per node)

// Node structure for k-ary tree
struct Node {
   int data;
   struct Node* children[MAX_CHILDREN];
};

// Function to create a new node
struct Node* createNode(int data) {
   struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
   newNode->data = data;

   // Initialize all child pointers to NULL
   for (int i = 0; i < MAX_CHILDREN; i++) {
      newNode->children[i] = NULL;
   }
   return newNode;
}

// Function to insert a new child node to a parent node
void insert(struct Node* parent, int data) {
   for (int i = 0; i < MAX_CHILDREN; i++) {
      if (parent->children[i] == NULL) {
         parent->children[i] = createNode(data);
         return;
      }
   }
   printf("Node %d already has maximum children (%d).\n", parent->data, MAX_CHILDREN);
}

// Function to print the tree structure
void printTree(struct Node* root) {
   if (root == NULL) return;

   printf("Node %d: ", root->data);
   for (int i = 0; i < MAX_CHILDREN; i++) {
      if (root->children[i] != NULL) {
         printf("%d ", root->children[i]->data);
      }
   }
   printf("\n");

   // Recursively print children
   for (int i = 0; i < MAX_CHILDREN; i++) {
      if (root->children[i] != NULL) {
         printTree(root->children[i]);
      }
   }
}

int main() {
   struct Node* root = createNode(1);

   // Insert children into root
   insert(root, 2);
   insert(root, 3);
   insert(root, 4);

   // Insert child nodes into node 3
   insert(root->children[1], 5);
   insert(root->children[1], 6);

   // Print the tree structure
   printTree(root);

   return 0;
}

Output

Following is the output of the above C program:

Node 1: 2 3 4 
Node 2: 
Node 3: 5 6 
Node 5: 
Node 6: 
Node 4: 
#include <iostream>
#include <vector>
using namespace std;

#define MAX_CHILDREN 3  

struct Node {
   int data;
   vector<Node*> children;

   Node(int val) : data(val) {
      children.resize(MAX_CHILDREN, nullptr);
   }
};

void insert(Node* parent, int data) {
   for (int i = 0; i < MAX_CHILDREN; i++) {
      if (parent->children[i] == nullptr) {
         parent->children[i] = new Node(data);
         return;
      }
   }
   cout << "Node " << parent->data << " full.\n";
}

void printTree(Node* root) {
   if (!root) return;
   cout << "Node " << root->data << ": ";
   for (int i = 0; i < MAX_CHILDREN; i++) {
      if (root->children[i]) {
         cout << root->children[i]->data << " ";
      }
   }
   cout << "\n";
   for (int i = 0; i < MAX_CHILDREN; i++) {
      if (root->children[i]) {
         printTree(root->children[i]);
      }
   }
}

int main() {
   Node* root = new Node(1);
   insert(root, 2);
   insert(root, 3);
   insert(root, 4);
   insert(root->children[1], 5);
   insert(root->children[1], 6);
   printTree(root);
   return 0;
}

Output

Following is the output of the above C++ program:

Node 1: 2 3 4
Node 2:
Node 3: 5 6
Node 5:
Node 6:
Node 4:
import java.util.*;

class Node {
   int data;
   Node children[];

   Node(int val) {
      data = val;
      children = new Node[3];
   }
}
public class Main {
   static final int MAX_CHILDREN = 3;
   static void insert(Node parent, int data) {
      for (int i = 0; i < MAX_CHILDREN; i++) {
         if (parent.children[i] == null) {
            parent.children[i] = new Node(data);
            return;
         }
      }
      System.out.println("Node " + parent.data + " full.");
   }

   static void printTree(Node root) {
      if (root == null) return;
      System.out.print("Node " + root.data + ": ");
      for (int i = 0; i < MAX_CHILDREN; i++) {
         if (root.children[i] != null) {
            System.out.print(root.children[i].data + " ");
         }
      }
      System.out.println();
      for (int i = 0; i < MAX_CHILDREN; i++) {
         if (root.children[i] != null) {
            printTree(root.children[i]);
         }
      }
   }

   public static void main(String[] args) {
      Node root = new Node(1);
      insert(root, 2);
      insert(root, 3);
      insert(root, 4);
      insert(root.children[1], 5);
      insert(root.children[1], 6);
      printTree(root);
   }
}

Output

Following is the output of the above Java program:

Node 1: 2 3 4
Node 2:
Node 3: 5 6
Node 5:
Node 6:
Node 4:
class Node:
   def __init__(self, data):
      self.data = data
      self.children = [None] * 3

def insert(parent, data):
   for i in range(3):
      if parent.children[i] is None:
         parent.children[i] = Node(data)
         return
   print(f"Node {parent.data} full.")

def printTree(root):
   if not root:
      return
   print(f"Node {root.data}: ", end="")
   for i in range(3):
      if root.children[i]:
         print(root.children[i].data, end=" ")
   print()
   for i in range(3):
      if root.children[i]:
         printTree(root.children[i])

root = Node(1)
insert(root, 2)
insert(root, 3)
insert(root, 4)
insert(root.children[1], 5)
insert(root.children[1], 6)
printTree(root)

Output

Following is the output of the above Python program:

Node 1: 2 3 4 
Node 2: 
Node 3: 5 6 
Node 5: 
Node 6: 
Node 4:

Traversal of K-Ary Tree

There are different ways to traverse a K-ary tree:

  • Inorder Traversal : Traverse the left subtree, visit the root node, and then traverse the right subtree.
  • Preorder Traversal : Visit the root node, traverse the left subtree, and then traverse the right subtree.
  • Postorder Traversal : Traverse the left subtree, traverse the right subtree, and then visit the root node.
  • Level Order Traversal : Traverse the tree level by level from left to right.

Algorithm for Inorder, Preorder, and Postorder Traversal

Follow the steps below to perform an inorder traversal of a K-ary tree:

1. Traverse the left subtree.
2. Visit the root node.
3. Traverse the right subtree.

Follow the steps below to perform a preorder traversal of a K-ary tree:

1. Visit the root node.
2. Traverse the left subtree.
3. Traverse the right subtree.

Follow the steps below to perform a postorder traversal of a K-ary tree:

1. Traverse the left subtree.
2. Traverse the right subtree.
3. Visit the root node.

Code to Perform Inorder, Preorder, and Postorder Traversal

Following is the code to perform inorder, preorder, and postorder traversal of a K-ary tree:

#include <stdio.h>
#include <stdlib.h>

#define MAX_CHILDREN 3

struct Node {
   int data;
   struct Node* children[MAX_CHILDREN];
};

struct Node* createNode(int data) {
   struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
   newNode->data = data;
   for (int i = 0; i < MAX_CHILDREN; i++) {
      newNode->children[i] = NULL;
   }
   return newNode;
}

void inorder(struct Node* root) {
   if (root == NULL) return;
   int mid = MAX_CHILDREN / 2;  // Find the middle index for ordering

   // First, traverse the left children (half of them)
   for (int i = 0; i < mid; i++) {
      inorder(root->children[i]);
   }

   printf("%d ", root->data);

   // Then, traverse the right children (remaining half)
   for (int j = mid; j < MAX_CHILDREN; j++) {
      inorder(root->children[j]);
   }
}

void preorder(struct Node* root) {
   if (root == NULL) return;
   printf("%d ", root->data);
   for (int i = 0; i < MAX_CHILDREN; i++) {
      preorder(root->children[i]);
   }
}

void postorder(struct Node* root) {
   if (root == NULL) return;
   for (int i = 0; i < MAX_CHILDREN; i++) {
      postorder(root->children[i]);
   }
   printf("%d ", root->data);
}

int main() {
   struct Node* root = createNode(1);
   root->children[0] = createNode(2);
   root->children[1] = createNode(3);
   root->children[2] = createNode(4);
   root->children[1]->children[0] = createNode(5);
   root->children[1]->children[1] = createNode(6);

   printf("Inorder Traversal: ");
   inorder(root);
   printf("\n");

   printf("Preorder Traversal: ");
   preorder(root);
   printf("\n");

   printf("Postorder Traversal: ");
   postorder(root);
   printf("\n");

   return 0;
}

Output

Following is the output of the above C program:

Inorder Traversal: 2 1 3 5 6 4
Preorder Traversal: 1 2 3 5 6 4
Postorder Traversal: 2 5 6 3 4 1
#include <iostream>
#include <vector>
using namespace std;

#define MAX_CHILDREN 3

struct Node {
   int data;
   vector<Node*> children;

   Node(int val) : data(val) {
      children.resize(MAX_CHILDREN, nullptr);
   }
};

void inorder(Node* root) {
   if (root == nullptr) return;
   int mid = root->children.size() / 2;  // Find the middle index for ordering

   // First, traverse the left children (half of them)
   for (int i = 0; i < mid; i++) {
      inorder(root->children[i]);
   }

   cout << root->data << " ";

   // Then, traverse the right children (remaining half)
   for (int j = mid; j < MAX_CHILDREN; j++) {
      inorder(root->children[j]);
   }
}

void preorder(Node* root) {
   if (root == nullptr) return;
   cout << root->data << " ";
   for (int i = 0; i < MAX_CHILDREN; i++) {
      preorder(root->children[i]);
   }
}

void postorder(Node* root) {
   if (root == nullptr) return;
   for (int i = 0; i < MAX_CHILDREN; i++) {
      postorder(root->children[i]);
   }
   cout << root->data << " ";
}

int main() {
   Node* root = new Node(1);
   root->children[0] = new Node(2);
   root->children[1] = new Node(3);
   root->children[2] = new Node(4);
   root->children[1]->children[0] = new Node(5);
   root->children[1]->children[1] = new Node(6);

   cout << "Inorder Traversal: ";
   inorder(root);
   cout << endl;

   cout << "Preorder Traversal: ";
   preorder(root);
   cout << endl;

   cout << "Postorder Traversal: ";
   postorder(root);
   cout << endl;

   return 0;
}

Output

Following is the output of the above C++ program:

Inorder Traversal: 2 1 3 5 6 4
Preorder Traversal: 1 2 3 5 6 4
Postorder Traversal: 2 5 6 3 4 1
import java.util.*;

class Node {
   int data;
   Node[] children;

   Node(int val) {
      data = val;
      children = new Node[3];
   }
}


public class Main {
   static final int MAX_CHILDREN = 3;

   static void inorder(Node root) {
      if (root == null) return;

      int mid = MAX_CHILDREN / 2;

      for (int i = 0; i < mid; i++) {
         inorder(root.children[i]);
      }

      System.out.print(root.data + " ");

      for (int k = mid; k < MAX_CHILDREN; k++) { // Changed 'j' to 'k'
         inorder(root.children[k]);
      }
   }

   static void preorder(Node root) {
      if (root == null) return;
      System.out.print(root.data + " ");
      for (int i = 0; i < MAX_CHILDREN; i++) {
         preorder(root.children[i]);
      }
   }

   static void postorder(Node root) {
      if (root == null) return;
      for (int i = 0; i < MAX_CHILDREN; i++) {
         postorder(root.children[i]);
      }
      System.out.print(root.data + " ");
   }

   public static void main(String[] args) {
      Node root = new Node(1);
      root.children[0] = new Node(2);
      root.children[1] = new Node(3);
      root.children[2] = new Node(4);
      root.children[1].children[0] = new Node(5);
      root.children[1].children[1] = new Node(6);

      System.out.print("Inorder Traversal: ");
      inorder(root);
      System.out.println();

      System.out.print("Preorder Traversal: ");
      preorder(root);
      System.out.println();

      System.out.print("Postorder Traversal: ");
      postorder(root);
      System.out.println();
   }
}

Output

Following is the output of the above Java program:

Inorder Traversal: 2 1 3 5 6 4
Preorder Traversal: 1 2 3 5 6 4
Postorder Traversal: 2 5 6 3 4 1
class Node:
   def __init__(self, data):
      self.data = data
      self.children = [None] * 3

def inorder(root):
    if not root:
        return

    mid = len(root.children) // 2  # Find the middle index for ordering

    # First, traverse the left children (half of them)
    for i in range(mid):
        inorder(root.children[i])

    # Print the current node
    print(root.data, end=" ")

    # Then, traverse the right children (remaining half)
    for i in range(mid, len(root.children)):
        inorder(root.children[i])

def preorder(root):
    if not root:
        return
    print(root.data, end=" ")
    for i in range(3):
        preorder(root.children[i])

def postorder(root):
   if not root:
      return

   for i in range(3):
      postorder(root.children[i])
   print(root.data, end=" ")

root = Node(1)
root.children[0] = Node(2)
root.children[1] = Node(3)
root.children[2] = Node(4)
root.children[1].children[0] = Node(5)
root.children[1].children[1] = Node(6)

print("Inorder Traversal: ", end="")
inorder(root)
print()

print("Preorder Traversal: ", end="")
preorder(root)
print()

print("Postorder Traversal: ", end="")
postorder(root)
print()

Output

Following is the output of the above Python program:

Inorder Traversal: 2 1 3 5 6 4
Preorder Traversal: 1 2 3 5 6 4
Postorder Traversal: 2 5 6 3 4 1

Level Order Traversal on K-ary Tree

Follow the steps below to perform a level order traversal of a K-ary tree:

1. Create a queue and enqueue the root node.
2. Repeat the following steps until the queue is empty:
   a. Dequeue a node from the queue.
   b. Print the data of the dequeued node.
   c. Enqueue all children of the dequeued node.

Code to Perform Level Order Traversal

Following is the code to perform a level order traversal of a K-ary tree:

#include <stdio.h>
#include <stdlib.h>

#define MAX_CHILDREN 3

struct Node {
   int data;
   struct Node* children[MAX_CHILDREN];
};

struct Node* createNode(int data) {
   struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
   newNode->data = data;
   for (int i = 0; i < MAX_CHILDREN; i++) {
      newNode->children[i] = NULL;
   }
   return newNode;
}

void levelOrder(struct Node* root) {
   if (root == NULL) return;

   struct Node* queue[100];
   int front = 0, rear = 0;
   queue[rear++] = root;

   while (front < rear) {
      struct Node* current = queue[front++];
      printf("%d ", current->data);

      for (int i = 0; i < MAX_CHILDREN; i++) {
         if (current->children[i] != NULL) {
            queue[rear++] = current->children[i];
         }
      }
   }
}

int main() {
   struct Node* root = createNode(1);
   root->children[0] = createNode(2);
   root->children[1] = createNode(3);
   root->children[2] = createNode(4);
   root->children[1]->children[0] = createNode(5);
   root->children[1]->children[1] = createNode(6);

   printf("Level Order Traversal: ");
   levelOrder(root);
   printf("\n");

   return 0;
}

Output

Following is the output of the above C program:

Level Order Traversal: 1 2 3 4 5 6
#include <iostream>
#include <queue>
using namespace std;

#define MAX_CHILDREN 3

struct Node {
   int data;
   vector<Node*> children;

   Node(int val) : data(val) {
      children.resize(MAX_CHILDREN, nullptr);
   }
};

void levelOrder(Node* root) {
   if (root == nullptr) return;

   queue<Node*> q;
   q.push(root);

   while (!q.empty()) {
      Node* current = q.front();
      q.pop();
      cout << current->data << " ";

      for (int i = 0; i < MAX_CHILDREN; i++) {
         if (current->children[i] != nullptr) {
            q.push(current->children[i]);
         }
      }
   }
}

int main() {
   Node* root = new Node(1);
   root->children[0] = new Node(2);
   root->children[1] = new Node(3);
   root->children[2] = new Node(4);
   root->children[1]->children[0] = new Node(5);
   root->children[1]->children[1] = new Node(6);

   cout << "Level Order Traversal: ";
   levelOrder(root);
   cout << endl;

   return 0;
}

Output

Following is the output of the above C++ program:

Level Order Traversal: 1 2 3 4 5 6
import java.util.*;

class Node {
   int data;
   Node children[];

   Node(int val) {
      data = val;
      children = new Node[3];
   }
}

public class Main {
   static final int MAX_CHILDREN = 3;
   static void levelOrder(Node root) {
      if (root == null) return;

      Queue<Node> queue = new LinkedList<>();
      queue.add(root);

      while (!queue.isEmpty()) {
         Node current = queue.poll();
         System.out.print(current.data + " ");

         for (int i = 0; i < MAX_CHILDREN; i++) {
            if (current.children[i] != null) {
               queue.add(current.children[i]);
            }
         }
      }
   }

   public static void main(String[] args) {
      Node root = new Node(1);
      root.children[0] = new Node(2);
      root.children[1] = new Node(3);
      root.children[2] = new Node(4);
      root.children[1].children[0] = new Node(5);
      root.children[1].children[1] = new Node(6);

      System.out.print("Level Order Traversal: ");
      levelOrder(root);
      System.out.println();
   }
}

Output

Following is the output of the above Java program:

Level Order Traversal: 1 2 3 4 5 6
from collections import deque

class Node:
   def __init__(self, data):
      self.data = data
      self.children = [None] * 3

def levelOrder(root):
    if not root:
        return
    
    q = deque()
    q.append(root)
    
    while q:
        current = q.popleft()
        print(current.data, end=" ")
    
        for i in range(3):
            if current.children[i]:
                q.append(current.children[i])

root = Node(1)
root.children[0] = Node(2)
root.children[1] = Node(3)
root.children[2] = Node(4)
root.children[1].children[0] = Node(5)
root.children[1].children[1] = Node(6)

print("Level Order Traversal: ", end="")
levelOrder(root)
print()

Output

Following is the output of the above Python program:

Level Order Traversal: 1 2 3 4 5 6

Search Operation on K-Ary Tree

Follow the steps below to search for a specific node in a K-ary tree:

1. Create a queue and enqueue the root node.
2. Repeat the following steps until the queue is empty:
   a. Dequeue a node from the queue.
   b. If the data of the dequeued node matches the search key, return true.
   c. Enqueue all children of the dequeued node.
3. If the search key is not found, return false.

Code to Search a Node in K-Ary Tree

Following is the code to search for a specific node in a K-ary tree:

#include <stdio.h>
#include <stdlib.h>

#define MAX_CHILDREN 3

struct Node {
   int data;
   struct Node* children[MAX_CHILDREN];
};

struct Node* createNode(int data) {
   struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
   newNode->data = data;
   for (int i = 0; i < MAX_CHILDREN; i++) {
      newNode->children[i] = NULL;
   }
   return newNode;
}

int search(struct Node* root, int key) {
   if (root == NULL) return 0;

   struct Node* queue[100];
   int front = 0, rear = 0;
   queue[rear++] = root;

   while (front < rear) {
      struct Node* current = queue[front++];
      if (current->data == key) return 1;

      for (int i = 0; i < MAX_CHILDREN; i++) {
         if (current->children[i] != NULL) {
            queue[rear++] = current->children[i];
         }
      }
   }
   return 0;
}

int main() {
   struct Node* root = createNode(1);
   root->children[0] = createNode(2);
   root->children[1] = createNode(3);
   root->children[2] = createNode(4);
   root->children[1]->children[0] = createNode(5);
   root->children[1]->children[1] = createNode(6);

   int key = 5;
   if (search(root, key)) {
      printf("Node %d found in the tree.\n", key);
   } else {
      printf("Node %d not found in the tree.\n", key);
   }

   return 0;
}

Output

Following is the output of the above C program:

Node 5 found in the tree.
#include <iostream>
#include <queue>
using namespace std;

#define MAX_CHILDREN 3

struct Node {
   int data;
   vector<Node*> children;

   Node(int val) : data(val) {
      children.resize(MAX_CHILDREN, nullptr);
   }
};

bool search(Node* root, int key) {
   if (root == nullptr) return false;

   queue<Node*> q;
   q.push(root);

   while (!q.empty()) {
      Node* current = q.front();
      q.pop();
      if (current->data == key) return true;

      for (int i = 0; i < MAX_CHILDREN; i++) {
         if (current->children[i] != nullptr) {
            q.push(current->children[i]);
         }
      }
   }
   return false;
}

int main() {
   Node* root = new Node(1);
   root->children[0] = new Node(2);
   root->children[1] = new Node(3);
   root->children[2] = new Node(4);
   root->children[1]->children[0] = new Node(5);
   root->children[1]->children[1] = new Node(6);

   int key = 5;
   if (search(root, key)) {
      cout << "Node " << key << " found in the tree." << endl;
   } else {
      cout << "Node " << key << " not found in the tree." << endl;
   }

   return 0;
}

Output

Following is the output of the above C++ program:

Node 5 found in the tree.
import java.util.*;

class Node {
   int data;
   Node children[];

   Node(int val) {
      data = val;
      children = new Node[3];
   }
}

public class Main {
   static final int MAX_CHILDREN = 3;
   static boolean search(Node root, int key) {
      if (root == null) return false;

      Queue<Node> queue = new LinkedList<>();
      queue.add(root);

      while (!queue.isEmpty()) {
         Node current = queue.poll();
         if (current.data == key) return true;

         for (int i = 0; i < MAX_CHILDREN; i++) {
            if (current.children[i] != null) {
               queue.add(current.children[i]);
            }
         }
      }
      return false;
   }

   public static void main(String[] args) {
      Node root = new Node(1);
      root.children[0] = new Node(2);
      root.children[1] = new Node(3);
      root.children[2] = new Node(4);
      root.children[1].children[0] = new Node(5);
      root.children[1].children[1] = new Node(6);

      int key = 5;
      if (search(root, key)) {
         System.out.println("Node " + key + " found in the tree.");
      } else {
         System.out.println("Node " + key + " not found in the tree.");
      }
   }
}

Output

Following is the output of the above Java program:

Node 5 found in the tree.
from collections import deque

class Node:
   def __init__(self, data):
      self.data = data
      self.children = [None] * 3

def search(root, key):
   if not root:
      return False
   
   q = deque()
   q.append(root)

   while q:
      current = q.popleft()
      if current.data == key:
         return True

      for i in range(3):
         if current.children[i]:
            q.append(current.children[i])

   return False

root = Node(1)
root.children[0] = Node(2)
root.children[1] = Node(3)
root.children[2] = Node(4)
root.children[1].children[0] = Node(5)
root.children[1].children[1] = Node(6)
key = 5

if search(root, key):
   print(f"Node {key} found in the tree.")
else:
   print(f"Node {key} not found in the tree.")

Output

Following is the output of the above Python program:

Node 5 found in the tree.

Applications of K-Ary Tree

K-ary tree is used in the following applications:

  • File systems
  • Routing tables
  • Database indexing
  • Multiway search trees
  • Heap data structure

Conclusion

In this tutorial, we learned about K-ary trees, their representation, and different operations like insertion, traversal, search, and level order traversal. We also discussed the applications of K-ary trees. You can now implement K-ary trees in your programs and solve problems related to them.

Advertisements