Javatpoint Logo
Javatpoint Logo

Cartesian Tree Sorting in C++

Cartesian Tree Sorting is a unique sorting algorithm that leverages the Cartesian tree information structure to achieve efficient sorting of a sequence of awesome numbers. To comprehend this set of rules, it is essential to delve into the concepts of Cartesian trees, their production, and the sorting sprocess.

Cartesian tree is a binary tree derived from a given sequence of distinct numbers. Each node in this tree represents an element from the input sequence and has key attributes: a value and an associated priority. The precedence of a node is determined using its function in the input sequence. Specifically, nodes closer to the beginning of the sequence have higher priorities than those appearing later. The production of a Cartesian tree involves a systematic process that iterates via the enter sequence.

As each element is encountered, a corresponding node is created and inserted into the tree while adhering to the rules that hold the precedence-based ordering. A stack-based approach is commonly employed all through this process, ensuring that the properties of a Cartesian tree are preserved as new nodes are added.

The insertion involves comparisons with existing nodes, leading to adjustments in the tree structure to hold the correct Cartesian tree properties. The algorithm's efficiency shines when dealing with sequences of distinct numbers, and its performance can be favorable in scenarios where the production of a Cartesian tree aligns with the overall computational objectives.

Method-1: Recursive Cartesian Tree Sort

Recursive Cartesian Tree Sort is an implementation of Cartesian Tree Sort, the usage of a recursive method to construct the Cartesian tree and perform in-order traversal. The Cartesian tree is a binary tree derived from a sequence of awesome numbers, and it performs an essential role in sorting the enter sequence.

Cartesian Tree:

The input sequence is constructed such that each node in the tree has a value corresponding to an element in the sequence, and the priorities of the nodes are determined through the order of the elements and the Cartesian tree property ensures that the in-order traversal of the tree yields the sorted sequence.

Recursive Approach:

The recursive Cartesian Tree Sort method involves dividing the problem into smaller subproblems through recursively constructing the Cartesian tree for subarrays.

Program:

Output:

5 10 40 30 28

Explanation:

Node Structure:

The 'Node' struct represents a node within the Cartesian tree. It comprises three components: 'value', which holds the node's value, and 'left' and 'right', which are pointers to the left and right children's nodes, respectively.

buildCartesianTree Function:

  • The buildCartesianTree function recursively constructs a Cartesian tree for a given subarray of the input array.
  • It takes three parameters: arr (the input array), start (the starting index of the current subarray), and end (the ending index of the current subarray). The base case checks if start > end, and if true, it returns nullptr, indicating an empty tree.
  • The function then finds the index of the minimum element in the current subarray. It initializes a Node with the value of the minimum element and recursively builds the left and right subtrees.

inOrderTraversal function:

  • The inOrderTraversal function performs an in-order traversal of the Cartesian tree. It takes a Node* root as a parameter and prints the values in sorted order.
  • The traversal involves visiting the left subtree, printing the current node's value, and then visiting the right subtree.

cartesianTreeSort function:

  • The cartesianTreeSort function is the entry point to the Cartesian Tree Sort algorithm. It takes the input array arr and its size n.
  • It calls buildCartesianTree to construct the Cartesian tree and then invokes inOrderTraversal to print the sorted sequence.

Main function:

In the main function, an example array arr is defined: {5, 10, 40, 30, 28}. The size of the array is calculated, and cartesianTreeSort is called with the array and its size.

The program prints the sorted sequence, which is the result of the Cartesian Tree Sort algorithm.

Complexity Analysis:

Time Complexity Analysis:

Build Cartesian Tree (buildCartesianTree function):

The function recursively constructs the Cartesian tree by traversing each element once.

At each level of the recursive function, it handles a consistent number of elements, involving tasks like finding the minimum value and creating a node.

The time it takes to build the Cartesian tree has a complexity of O(n log n), where 'n' signifies the quantity of elements contained in the input array.

In-order Traversal (inOrderTraversal function):

In-order traversal visits each node exactly once.

The time complexity of in-order traversal is O(n), where 'n' is the number of nodes in the Cartesian tree.

Combining the time complexities of building the Cartesian tree and performing in-order traversal, the total time complexity of Cartesian Tree Sort is O(n log n).

Space Complexity Analysis:

Node Structures:

Every element in the input array corresponds to a node within the Cartesian tree. The space needed to store these nodes grows in proportion to the number of elements in the array.

The space complexity for node structures is O(n).

Recursion Stack:

The recursive calls in the buildCartesianTree function contribute to the call stack space.

The maximum depth of the recursion used in building the Cartesian tree corresponds to the tree's height. In the worst-case scenario, the height of the Cartesian tree is log(n), where 'n' represents the number of elements contained within the input array.

The space complexity due to the recursion stack is O(log n).

Combining the space complexities of node structures and the recursion stack, the overall space complexity of Cartesian Tree Sort is O(n + log n).

In practice, the dominant factor is the space required for node structures, and the recursion stack's contribution is comparatively small.

Method-2: Iterative Cartesian Tree Sort with Stack

Iterative Cartesian Tree Sort with a stack involves using an iterative approach and a stack data structure to build the Cartesian tree. This method avoids the recursive calls typically used in the recursive approach. The stack is employed to keep track of the partial Cartesian tree during the iteration. The main steps include node construction, stack-based tree construction, and in-order traversal for sorting.

Program:

Output:

Sorted Sequence: 5 10 40 30 28 

Explanation:

Node Construction:

  • The algorithm begins by iterating through the input sequence of distinct numbers.
  • For each element, a corresponding node is created. This node contains the element's value, its index in the sequence, and initializes left and right pointers to nullptr.

Stack-Based Tree Construction:

  • A stack (s) is utilized to maintain a partial Cartesian tree during the iteration. For each node, its value is compared with the top of the stack.
  • Suppose the current node's value is smaller than the top of the stack. In that case, it means the current node should be the left child of the top node on the stack, and this process is repeated until an appropriate position for the current node is found.
  • The current node is then pushed onto the stack.

Final Cartesian Tree:

The top of the stack after the iteration represents the root of the Cartesian tree.

In-Order Traversal for Sorting:

  • To obtain the sorted sequence, the algorithm performs an in-order traversal of the Cartesian tree. During the traversal, the algorithm uses a second stack (inOrderStack) to keep track of nodes.
  • The traversal begins from the root and moves left until the leftmost node is reached. Nodes are pushed onto the inOrderStack during this process.
  • Once the leftmost node is reached, it is popped from the inOrderStack, its value is printed, and the algorithm moves to its right child. This process continues until all nodes are processed.

Key Points:

  • The algorithm efficiently maintains the Cartesian tree structure using a stack, avoiding recursive calls. It takes advantage of the stack to adjust the Cartesian tree properties during the iteration.
  • The in-order traversal ensures that the sorted sequence is obtained from the Cartesian tree.
  • Iterative Cartesian Tree Sort with Stack is an efficient algorithm for sorting a sequence using an iterative approach, a stack, and the properties of Cartesian trees. It achieves a linear time complexity and linear space complexity, making it a practical sorting solution.

Complexity Analysis:

Time Complexity:

Node Construction and Stack Operations:

Each element present in the input sequence is handled only once. For every element, the algorithm executes a fixed number of stack operations.

Considering node construction and stack operations, the overall time complexity amounts to O(n), where 'n' denotes the number of elements within the input sequence.

In-Order Traversal:

The in-order traversal is performed once for each node in the Cartesian tree.

The time complexity of in-order traversal is O(n), where 'n' is the number of nodes in the Cartesian tree.

Combining the complexities of node construction, stack operations, and in-order traversal, the total time complexity of Iterative Cartesian Tree Sort with Stack is O(n).

Space Complexity:

Node Structures:

Every element in the input array represents a node within the Cartesian tree. The space necessary to store these nodes increases the number of elements in the array.

The space complexity for node structures is O(n).

Stacks (s and inOrderStack):

The algorithm uses two stacks (s for tree construction and inOrderStack for traversal).

The maximum size of each stack is proportional to the height of the Cartesian tree, which is log(n) in the worst case.

The space complexity for both stacks is O(log n).

Combining the space complexities of node structures and the two stacks, the overall space complexity of Iterative Cartesian Tree Sort with Stack is O(n + log n).

In practice, the dominant factor is the space required for node structures, and the contribution from the stacks is comparatively small.

The algorithm is efficient with a linear time complexity, making it suitable for sorting large datasets. The space complexity is also reasonable, and the algorithm performs well in practice.

Method-3: Using Segment Tree

Cartesian Tree Sort using a Segment Tree involves efficiently finding the minimum element in a range. This approach builds the Cartesian tree by selecting the minimum element in each range of the input array. The key idea is to use a Segment Tree data structure to efficiently answer range minimum queries.

Segment Tree Overview:

A Segment Tree is a binary tree data structure used for storing information about intervals or segments.

Each leaf node of the Segment Tree represents an element from the the input array.

Each non-leaf node stores the minimum value of its children.

Cartesian Tree Sort using Segment Tree:

Node Structure:

A Node represents a node within the Cartesian tree structure. Each node includes the minimum value, the index of that minimum value, and pointers or references to its left and right children nodes.

Build Cartesian Tree:

The Cartesian tree is built recursively using the minimum value obtained from the Segment Tree.

During each step, the minimum element and index in the current range are determined by utilizing the Segment Tree query operation. A Node is then generated using this minimum value and index. This process is iterated for both the left and right subranges accordingly.

Segment Tree Operations:

Build:

The Segment Tree is built to represent the minimum values in different subranges of the input array.

The build operation is typically performed bottom-up.

Query:

The query operation is used to find the minimum element and its index in a given range.

It efficiently finds the minimum value within a specified range in logarithmic time.

In-Order Traversal:

After building the Cartesian tree, an in-order traversal is performed to output the sorted sequence.

Program:

Output:

Sorted Sequence: 5 10 40 30 28

Explanation:

Node Structure (Node):

The Node structure represents a node in the Cartesian tree.

It contains three important attributes:

value: Represents the minimum value in the range.

index: Holds the index of the minimum value.

left and right: Pointers to the left and right children of the node.

Build Cartesian Tree (buildCartesianTree):

This function recursively builds the Cartesian tree. The key operation is finding the minimum value and its index in the given range using a Segment Tree query.

For each range, a node is created with the minimum value and index, and the function is called recursively on the left and right subranges.

This ensures that the Cartesian tree is constructed by selecting the minimum element in each range.

Build Segment Tree (buildSegmentTree):

This function initializes and builds the Segment Tree.

It sets up the necessary data structures and invokes the buildCartesianTree function to create the Cartesian tree using the Segment Tree.

In-Order Traversal (inOrderTraversal):

  • The inOrderTraversal function performs an in-order traversal of the Cartesian tree.
  • It prints the elements in sorted order because in-order traversal of a Cartesian tree results in a sorted sequence.

Cartesian Tree Sort (cartesianTreeSort):

  • The cartesianTreeSort function is the entry point for the Cartesian Tree Sort using a Segment Tree.
  • It calls the necessary functions to initialize and build the Segment Tree, construct the Cartesian tree, and perform the in-order traversal for sorting. The output is the sorted sequence of elements.

Output:

The output of the program is the sorted sequence of elements obtained through Cartesian Tree Sort using a Segment Tree.

  • Cartesian Tree Sort using a Segment Tree efficiently combines the principles of Cartesian trees and Segment trees.
  • It leverages the Segment Tree to find the minimum value in each subrange, constructing a Cartesian tree that inherently represents the sorted order of the input sequence.
  • The ultimate sorted sequence is achieved by executing an in-order traversal of the Cartesian tree.

Complexity Analysis:

Time Complexity:

Build Cartesian Tree (buildCartesianTree):

The build operation involves constructing the Cartesian tree by selecting the minimum element in each range.

For each node in the Cartesian tree, a Segment Tree query is performed to find the minimum value in a subrange.

Since there are O(N) nodes in the Cartesian tree, the overall time complexity is O(N log N) for building the Cartesian tree.

Build Segment Tree (buildSegmentTree):

The build operation for the Segment Tree involves initializing and constructing the tree.

Therefore, the overall time complexity for building the Segment Tree is O(N).

In-Order Traversal (inOrderTraversal):

The in-order traversal of the Cartesian tree is a linear-time operation, as each node is visited once.

The time complexity of in-order traversal is O(N), where N is the number of nodes in the Cartesian tree.

Cartesian Tree Sort (cartesianTreeSort):

The overall time complexity is dominated by the construction of the Cartesian tree, which is O(N log N).

Space Complexity:

Node Structure (Node):

Each node in the Cartesian tree requires constant space, as it only stores a few variables (value, index, left, right).

The space complexity for each node is O(1).

Build Cartesian Tree (buildCartesianTree):

The space complexity is determined by the number of nodes in the Cartesian tree.

Since there are O(N) nodes in the Cartesian tree, the space complexity is O(N).

Build Segment Tree (buildSegmentTree):

The space complexity for the Segment Tree is O(4N) because a Segment Tree is typically implemented using an array, and for N elements, 4N nodes are needed.

Each node stores information about a range in the input array.

In-Order Traversal (inOrderTraversal):

The space required for in-order traversal is minimal, typically O(1), as it doesn't use additional data structures that grow with the input size.

Cartesian Tree Sort (cartesianTreeSort):

The overall space complexity is dominated by the Cartesian tree, which is O(N).

Conclusion:

Cartesian Tree Sorting is a unique approach that utilizes the Cartesian tree data structure. The elegance of this algorithm lies in its seamless integration of tree construction with the sorting process. This integration results in an efficient and intuitive method for sorting sequences comprising distinct numbers. Understanding the principles behind Cartesian trees, their construction, and subsequent in-order traversal offers insights into the theoretical foundation and practical application of Cartesian Tree Sorting.







Youtube For Videos Join Our Youtube Channel: Join Now

Feedback


Help Others, Please Share

facebook twitter pinterest

Learn Latest Tutorials


Preparation


Trending Technologies


B.Tech / MCA