Lisp - Binary Tree



A Binary Search Tree (BST) is a tree in which all the nodes follow the below-mentioned properties −

  • The left sub-tree of a node has a key less than or equal to its parent node's key.

  • The right sub-tree of a node has a key greater than or equal to its parent node's key.

Thus, BST divides all its sub-trees into two segments; the left sub-tree and the right sub-tree and can be defined as −

left_subtree (keys) ≤ node (key) ≤ right_subtree (keys)

Binary Tree Representation

BST is a collection of nodes arranged in a way where they maintain BST properties. Each node has a key and an associated value. While searching, the desired key is compared to the keys in BST and if found, the associated value is retrieved.

Following is a pictorial representation of BST −

Tree Traversal

We observe that the root node key (27) has all less-valued keys on the left sub-tree and the higher valued keys on the right sub-tree.

Basic Operations

Following are the basic operations of a Binary Search Tree −

  • Search − Searches an element in a tree.

  • Insert − Inserts an element in a tree.

  • Pre-order Traversal − Traverses a tree in a pre-order manner.

  • In-order Traversal − Traverses a tree in an in-order manner.

  • Post-order Traversal − Traverses a tree in a post-order manner.

Binary Tree Representation

In Lisp, binary tree is represented as (node left-subtree right-subtree). We can define a binary tree as list of lists as shown in example below:

; define a binary tree
(defvar binary-tree '(27 (14 (10 nil nil) (19 nil nil)) (35 (31 nil nil) (42 nil nil))))

; print tree
(print binary-tree)

Output

When you execute the code, it returns the following result −

(27 (14 (10 NIL NIL) (19 NIL NIL)) (35 (31 NIL NIL) (42 NIL NIL))) 

Here 27 is the root node, 14 is the left node, 35 is the right node, 10 is left child of 14 and so on.

Key Concepts and Operations

Tree Traversal

Binary trees are travered using recursive functions in different orders.

  • Pre-Order Traversal (Node, Left, Right)

  • In-Order Traversal (Left, Node, Right)

  • Post-Order Traversal (Left, Right, Node)

Accessing Elements of the Tree

Following functions are used to access elements of a binary tree.

  • car − to access value of a node

  • cadr − equivalent to car (cdr ...); to access the left sub tree

  • caddr − equivalent to car (cdr (cdr ...)); to access the right sub tree

Traversing a Binary Tree

Following example shows how to traverse a tree using pre-order traversal.

main.lisp

; define preorder traversal function
(defun preorder-traversal (tree)
   (when tree
      (print (car tree)) ; Visit the node and print the value
      (preorder-traversal (cadr tree)) ; Traverse left tree
      (preorder-traversal (caddr tree)))) ; Traverse right tree

; define the tree
(defvar my-tree '(27 (14 (10 NIL NIL) (19 NIL NIL)) (35 (31 NIL NIL) (42 NIL NIL))))

(preorder-traversal my-tree)

Output

When you execute the code, it returns the following result −

27 
14 
10 
19 
35 
31 
42 

Explanation

  • defun− defines the function.

  • when− executes block when tree is not nil.

  • car tree&minus returns the first element as root and print it.

  • cadr tree− equivalent to (car (cdr tree)) returns the second element as left subtree.

  • caddr tree− equivalent to (car (cdr (cdr tree))) returns the third element as right subtree.

Recursion is the key here to traverse the subtrees using recursive function call.

Advertisements