      "    if node is None:\n",
      "        return None\n",
      "    if node.left is None:\n",
      "        return node.data\n",
      "    return left_most_node(node.left)\n",
      "\n",
      "\n",
      "def bst_successor(node):\n",
      "    if node is None:\n",
      "        raise Exception('Invalid input node')\n",
      "    if node.right is not None:\n",
      "        return left_most_node(node.right)\n",
      "    else:\n",
      "        parent = node.parent\n",
      "        while parent is not None and parent.left is not node:\n",
      "            node = node.parent\n",
      "            parent = node.parent\n",
      "        if parent is None:\n",
      "            # We reached the root, the original input node\n",
      "            # must be the largest element in the tree.\n",
      "            return None\n",
      "        return parent.data"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
 
</s> remove     "def left_most_node(node):\n",
    "    if node is None:\n",
    "        return None\n",
    "    if node.left is None:\n",
 </s> add     "class BstSuccessor(object):\n",
    "\n",
    "    def get_next(self, node):\n",
    "        if node is None:\n",
    "            raise Exception('Invalid input node')\n",
    "        if node.right is not None:\n",
    "            return self._left_most(node.right)\n",
    "        return self._next_ancestor(node)\n",
    "\n",
    "    def _left_most(self, node):\n",
    "        if node.left is not None:\n",
    "            return self._left_most(node.left)\n", </s> remove     "def bst_successor(node):\n",
    "    # TODO: Implement me\n",
    "    pass"
 </s> add     "class BstSuccessor(object):\n",
    "\n",
    "    def get_next(self, node):\n",
    "        # TODO: Implement me\n",
    "        pass" </s> remove     "        bst_successor(None)\n",
 </s> add     "        bst_successor = BstSuccessor()\n",
    "        bst_successor.get_next(None)\n", </s> remove     "        bst_successor(None)\n",
 </s> add     "        bst_successor = BstSuccessor()\n",
    "        bst_successor.get_next(None)\n", </s> remove     "        nodes[3] = insert(node, 3)\n",
    "        nodes[8] = insert(node, 8)\n",
    "        nodes[2] = insert(node, 2)\n",
    "        nodes[4] = insert(node, 4)\n",
    "        nodes[6] = insert(node, 6)\n",
    "        nodes[12] = insert(node, 12)\n",
    "        nodes[1] = insert(node, 1)\n",
    "        nodes[7] = insert(node, 7)\n",
    "        nodes[10] = insert(node, 10)\n",
    "        nodes[15] = insert(node, 15)\n",
    "        nodes[9] = insert(node, 9)\n",
    "\n",
    "        assert_equal(bst_successor(nodes[4]), 5)\n",
    "        assert_equal(bst_successor(nodes[5]), 6)\n",
    "        assert_equal(bst_successor(nodes[8]), 9)\n",
    "        assert_equal(bst_successor(nodes[15]), None)\n",
 </s> add     "        bst = Bst(nodes[5])\n",
    "        nodes[3] = bst.insert(3)\n",
    "        nodes[8] = bst.insert(8)\n",
    "        nodes[2] = bst.insert(2)\n",
    "        nodes[4] = bst.insert(4)\n",
    "        nodes[6] = bst.insert(6)\n",
    "        nodes[12] = bst.insert(12)\n",
    "        nodes[1] = bst.insert(1)\n",
    "        nodes[7] = bst.insert(7)\n",
    "        nodes[10] = bst.insert(10)\n",
    "        nodes[15] = bst.insert(15)\n",
    "        nodes[9] = bst.insert(9)\n",
    "\n",
    "        bst_successor = BstSuccessor()\n",
    "        assert_equal(bst_successor.get_next(nodes[4]), 5)\n",
    "        assert_equal(bst_successor.get_next(nodes[5]), 6)\n",
    "        assert_equal(bst_successor.get_next(nodes[8]), 9)\n",
    "        assert_equal(bst_successor.get_next(nodes[15]), None)\n",
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
      "    if node is None:\n",
      "        return None\n",
      "    if node.left is None:\n",
      "        return node.data\n",
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
    "\n",
    "    def _next_ancestor(self, node):\n",
    "        if node.parent is not None:\n",
    "            if node.parent.data > node.data:\n",
    "                return node.parent.data\n",
    "            return self._next_ancestor(node.parent)\n",
    "        # We reached the root, the original input node\n",
    "        # must be the largest element in the tree.\n",
    "        return None"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Move bst successor to a class 
graphs_trees/bst_successor/bst_successor_solution.ipynb