|
1 | | -from pydatastructs.utils import TreeNode |
| 1 | +from pydatastructs.utils import TreeNode, CartesianTreeNode |
2 | 2 | from pydatastructs.miscellaneous_data_structures import Stack |
3 | 3 | from pydatastructs.linear_data_structures import ( |
4 | 4 | OneDimensionalArray, DynamicOneDimensionalArray) |
5 | 5 | from pydatastructs.linear_data_structures.arrays import ArrayForTrees |
6 | 6 | from collections import deque as Queue |
| 7 | +import random |
7 | 8 | from copy import deepcopy |
8 | 9 |
|
9 | 10 | __all__ = [ |
|
12 | 13 | 'BinarySearchTree', |
13 | 14 | 'BinaryTreeTraversal', |
14 | 15 | 'BinaryIndexedTree', |
| 16 | + 'CartesianTree', |
| 17 | + 'Treap', |
15 | 18 | 'SplayTree' |
16 | 19 | ] |
17 | 20 |
|
@@ -642,6 +645,143 @@ def _left_rotate(self, j, k): |
642 | 645 | if kp is None: |
643 | 646 | self.root_idx = k |
644 | 647 |
|
| 648 | +class CartesianTree(SelfBalancingBinaryTree): |
| 649 | + """ |
| 650 | + Represents cartesian trees. |
| 651 | +
|
| 652 | + Examples |
| 653 | + ======== |
| 654 | +
|
| 655 | + >>> from pydatastructs.trees import CartesianTree as CT |
| 656 | + >>> c = CT() |
| 657 | + >>> c.insert(1, 4, 1) |
| 658 | + >>> c.insert(2, 3, 2) |
| 659 | + >>> child = c.tree[c.root_idx].left |
| 660 | + >>> c.tree[child].data |
| 661 | + 1 |
| 662 | + >>> c.search(1) |
| 663 | + 0 |
| 664 | + >>> c.search(-1) is None |
| 665 | + True |
| 666 | + >>> c.delete(1) is True |
| 667 | + True |
| 668 | + >>> c.search(1) is None |
| 669 | + True |
| 670 | + >>> c.delete(2) is True |
| 671 | + True |
| 672 | + >>> c.search(2) is None |
| 673 | + True |
| 674 | +
|
| 675 | + References |
| 676 | + ========== |
| 677 | +
|
| 678 | + .. [1] https://www.cs.princeton.edu/courses/archive/spr09/cos423/Lectures/geo-st.pdf |
| 679 | +
|
| 680 | + See Also |
| 681 | + ======== |
| 682 | +
|
| 683 | + pydatastructs.trees.binary_tree.SelfBalancingBinaryTree |
| 684 | + """ |
| 685 | + @classmethod |
| 686 | + def methods(cls): |
| 687 | + return ['__str__', 'insert', 'delete'] |
| 688 | + |
| 689 | + def _bubble_up(self, node_idx): |
| 690 | + node = self.tree[node_idx] |
| 691 | + parent_idx = self.tree[node_idx].parent |
| 692 | + parent = self.tree[parent_idx] |
| 693 | + while (node.parent is not None) and (parent.priority > node.priority): |
| 694 | + if parent.right == node_idx: |
| 695 | + self._left_rotate(parent_idx, node_idx) |
| 696 | + else: |
| 697 | + self._right_rotate(parent_idx, node_idx) |
| 698 | + node = self.tree[node_idx] |
| 699 | + parent_idx = self.tree[node_idx].parent |
| 700 | + if parent_idx is not None: |
| 701 | + parent = self.tree[parent_idx] |
| 702 | + if node.parent is None: |
| 703 | + self.tree[node_idx].is_root = True |
| 704 | + |
| 705 | + def _trickle_down(self, node_idx): |
| 706 | + node = self.tree[node_idx] |
| 707 | + while node.left is not None or node.right is not None: |
| 708 | + if node.left is None: |
| 709 | + self._left_rotate(node_idx, self.tree[node_idx].right) |
| 710 | + elif node.right is None: |
| 711 | + self._right_rotate(node_idx, self.tree[node_idx].left) |
| 712 | + elif self.tree[node.left].priority < self.tree[node.right].priority: |
| 713 | + self._right_rotate(node_idx, self.tree[node_idx].left) |
| 714 | + else: |
| 715 | + self._left_rotate(node_idx, self.tree[node_idx].right) |
| 716 | + node = self.tree[node_idx] |
| 717 | + |
| 718 | + def insert(self, key, priority, data=None): |
| 719 | + super(CartesianTree, self).insert(key, data) |
| 720 | + node_idx = super(CartesianTree, self).search(key) |
| 721 | + node = self.tree[node_idx] |
| 722 | + new_node = CartesianTreeNode(key, priority, data) |
| 723 | + new_node.parent = node.parent |
| 724 | + new_node.left = node.left |
| 725 | + new_node.right = node.right |
| 726 | + self.tree[node_idx] = new_node |
| 727 | + if node.is_root: |
| 728 | + self.tree[node_idx].is_root = True |
| 729 | + else: |
| 730 | + self._bubble_up(node_idx) |
| 731 | + |
| 732 | + def delete(self, key, **kwargs): |
| 733 | + balancing_info = kwargs.get('balancing_info', False) |
| 734 | + node_idx = super(CartesianTree, self).search(key) |
| 735 | + if node_idx is not None: |
| 736 | + self._trickle_down(node_idx) |
| 737 | + return super(CartesianTree, self).delete(key, balancing_info = balancing_info) |
| 738 | + |
| 739 | + def __str__(self): |
| 740 | + to_be_printed = ['' for i in range(self.tree._last_pos_filled + 1)] |
| 741 | + for i in range(self.tree._last_pos_filled + 1): |
| 742 | + if self.tree[i] is not None: |
| 743 | + node = self.tree[i] |
| 744 | + to_be_printed[i] = (node.left, node.key, node.priority, node.data, node.right) |
| 745 | + return str(to_be_printed) |
| 746 | + |
| 747 | +class Treap(CartesianTree): |
| 748 | + """ |
| 749 | + Represents treaps. |
| 750 | +
|
| 751 | + Examples |
| 752 | + ======== |
| 753 | +
|
| 754 | + >>> from pydatastructs.trees import Treap as T |
| 755 | + >>> t = T() |
| 756 | + >>> t.insert(1, 1) |
| 757 | + >>> t.insert(2, 2) |
| 758 | + >>> t.search(1) |
| 759 | + 0 |
| 760 | + >>> t.search(-1) is None |
| 761 | + True |
| 762 | + >>> t.delete(1) is True |
| 763 | + True |
| 764 | + >>> t.search(1) is None |
| 765 | + True |
| 766 | + >>> t.delete(2) is True |
| 767 | + True |
| 768 | + >>> t.search(2) is None |
| 769 | + True |
| 770 | +
|
| 771 | + References |
| 772 | + ========== |
| 773 | +
|
| 774 | + .. [1] https://en.wikipedia.org/wiki/Treap |
| 775 | +
|
| 776 | + """ |
| 777 | + @classmethod |
| 778 | + def methods(cls): |
| 779 | + return ['insert'] |
| 780 | + |
| 781 | + def insert(self, key, data=None): |
| 782 | + priority = random.random() |
| 783 | + super(Treap, self).insert(key, priority, data) |
| 784 | + |
645 | 785 | class AVLTree(SelfBalancingBinaryTree): |
646 | 786 | """ |
647 | 787 | Represents AVL trees. |
|
0 commit comments