皇冠体育的博彩平台支持多种语言,包括中文、英文、日文等。香港六合彩真人百家乐博彩网站活动_ \ 前边先容的堆结构只可对数据进行部分排序,也即是它只可知说念部分元素的排序,举例从根节点开赴,沿着左孩子或右孩子前行,咱们能得知所遍历的元素一定是递加(小堆)或是递减(大堆)相干,然则咱们无法得知左子树与右子树两部分节点的排序相干。 在好多哄骗场景下,咱们不但需要堆的特色,举例快速知说念数据最大值或最小值,同期还需要知说念元素的排序信息,因此本节咱们望望如何已毕鱼和熊掌如何兼得。假定咱们有一系列数据,它的元素由两部分构成,一部分对应商品的称号,其类型为字符串,一部分对应商品的货存数目,类型为整形,咱们既需要将商品笔据其称号排序,同期咱们又需要快速查询当前货存最小的商品,咱们如何预备相应的算法和数据结构来应承这么特色呢。 举个例子,如下图: 香港六合彩真人百家乐从上图看,它对应元素字符串是排序二叉树,因此根节点左子树对应元素的字符串齐小于根字符串,同期右子树对应的字符串齐大于根节点字符串,同期每个元素还对应着相应商品的货存数目,咱们需要实时掌执当前货存最少的商品,这么技术在其奢靡之前飞速补货。然则从上图不错看到,要保证字符串的排序性就得糟跶关于商品数目的小堆性质,举例上图中water对应的货存与wine对应的货存违背了小堆的性质,面前问题是如安在保证字符串排序的情况下,确保数目同期能应承小堆性质。 最初咱们先界说一下数据结构: zh皇冠足球源码真人娱乐class 香港六合彩色碟Node: def __init__(self, key: str, priority: float): self._key = key self._priority = priority self._left: Node = None self._right: Node = None self._parent: Node = None @property def left(self): return self._left @property def right(self): return self._right @property def parent(self): return self._parent @left.setter def left(self, node): self._left = node if node is not None: node.parent = self @right.setter def right(self, node): self._right = node if node is not None: node.parent = self @parent.setter def parent(self, node): self._parent = node def is_root(self) -> bool: if self.parent is None: return True return False def __repr__(self): return "({}, {})".format(self._key, self._priority) def __str__(self): repr_str: str = "" repr_str += repr(self) if self.parent is not None: repr_str += " parent: " + repr(self.parent) else: repr_str += " parent: None" if self.left is not None: repr_str += " left: " + repr(self.left) else: repr_str += " left: None" if self.right is not None: repr_str += " right: " + repr(self.right) else: repr_str += " right: None" return repr_str class Treap: def __init__(self): self.root : Node = None 当前问题是,当上图所示的矛盾出当前,咱们如何营救,使得字符串也曾保持排序性质,同期货存数值能应承小堆性质。咱们需要笔据几种情况选拔不同操作,最初看第一种,欧博真人平台如下图: 皇冠hg86a从上图看到,一种情况是父节点与左孩子在数值上违背了堆的性质,此时咱们试验一种叫右旋转操作,其行径是,1,Beer节点逆时针旋转,替换其父节点;2,父节点Cabbage顺时针旋转,成为Beer的右孩子节点;3,蓝本Beer的右孩子节点转动为Cabbage的左孩子节点;完成后效果如下图所示: 皇冠客服飞机:@seo3687 不错看到,此时字符串也曾保持排序二叉树性质,同期数值对应的小堆性质也获取了应承。咱们望望代码已毕: class Treap: def __init__(self): self._root: Node = None def right_rotate(self, x: Node): if x is None or x.is_root() is True: return y = x.parent if y.left != x: # 必须是左孩子技术右旋转 return p = y.parent if p is not None: # 试验右旋转 if p.left == y: p.left = x else: p.right = x else: self._root = x y.left = x.right x.right = y 接下来咱们构造一些数据测试一下上头的已毕是否正确: def setup_right_rotate(): flour: Node = Node("Flour", 10) cabbage: Node = Node("Cabbage", 77) beer: Node = Node("Beer", 76) bacon: Node = Node("Bacon", 95) butter: Node = Node("Butter", 86) flour.parent = None flour.left = cabbage flour.right = None cabbage.left = beer beer.left = bacon beer.right = butter return flour, beer def print_treap(n: Node): if n is None: return print(n) print_treap(n.left) print_treap(n.right) treap = Treap() root, x , cabbage = setup_right_rotate() print("---------before right rotate---------:") print_treap(root) treap.right_rotate(x) print("-------after right rotate-------") print_treap(root) 上头代码试验后输出内容如下: 每年的农历五月初五是端午节,在古代又被称为“端阳节”或“龙舟节”,是我国的传统节日之一。“端午食粽”也已经成为我们国家饮食风俗和文化传承的一个重要部分。 ---------before right rotate---------: (Flour, 10) parent: None left: (Cabbage, 77) right: None (Cabbage, 77) parent: (Flour, 10) left: (Beer, 76) right: (Eggs, 129) (Beer, 76) parent: (Cabbage, 77) left: (Bacon, 95) right: (Butter, 86) (Bacon, 95) parent: (Beer, 76) left: None right: None (Butter, 86) parent: (Beer, 76) left: None right: None (Eggs, 129) parent: (Cabbage, 77) left: None right: None -------after right rotate------- (Flour, 10) parent: None left: (Beer, 76) right: None (Beer, 76) parent: (Flour, 10) left: (Bacon, 95) right: (Cabbage, 77) (Bacon, 95) parent: (Beer, 76) left: None right: None (Cabbage, 77) parent: (Beer, 76) left: (Butter, 86) right: (Eggs, 129) (Butter, 86) parent: (Cabbage, 77) left: None right: None (Eggs, 129) parent: (Cabbage, 77) left: None right: None 对比右旋转前后输出的二叉树看,旋转后的二叉树打印信息的确跟上头咱们旋转后对应的图像是一致的。接下来咱们已毕左旋转,先把上图中cabbage节点对应的值改成75,这么它与父节点就违背了小堆性质: 博彩网站活动咱们要作念的是:1,把cabbage节点向“左”旋转到beer的位置;2,beer的父节点建筑为cabbage;3:beer的右孩子建筑为cabbage的左孩子;4,cabbage的左孩子造成beer;左旋转后二叉树应该成形如下: ag体育官网从上图看,左旋转后,字符串也曾保持二叉树排序性,同期数值的排放也死守小堆原则,咱们看相应的代码已毕: 皇冠澳门影院class Treap: ... def left_rotate(self, x : Node): if x is None or x.is_root() is True: return y = x.parent if y.right is not x: # 只须右孩子技术左旋转 return p = y.parent if p is not None: if p.left is y: p.left = x else: p.right = x else: self._root = x y.right = x.left x.left = y 为了测试上头代码已毕,咱们最初把cabbage的值修改,然后调用上头代码: 体育代理专员cabbage._priority = 75 print("-------before left rotate--------") print_treap(root) treap.left_rotate(cabbage) print("-------after left rotate---------") print_treap(root) 代码启动后输出效果为: -------before left rotate-------- (Flour, 10) parent: None left: (Beer, 76) right: None (Beer, 76) parent: (Flour, 10) left: (Bacon, 95) right: (Cabbage, 75) (Bacon, 95) parent: (Beer, 76) left: None right: None (Cabbage, 75) parent: (Beer, 76) left: (Butter, 86) right: (Eggs, 129) (Butter, 86) parent: (Cabbage, 75) left: None right: None (Eggs, 129) parent: (Cabbage, 75) left: None right: None -------after left rotate--------- (Flour, 10) parent: None left: (Cabbage, 75) right: None (Cabbage, 75) parent: (Flour, 10) left: (Beer, 76) right: (Eggs, 129) (Beer, 76) parent: (Cabbage, 75) left: (Bacon, 95) right: (Butter, 86) (Bacon, 95) parent: (Beer, 76) left: None right: None (Butter, 86) parent: (Beer, 76) left: None right: None (Eggs, 129) parent: (Cabbage, 75) left: None right: None 输出效果的态状与上图左旋转后的效果是一致的。由于Treap相干于元素的key是排序二叉树,因此在给定一个字符串后,咱们很容易查询字符串是否在Treap中,其骨子即是排序二叉树的搜索,其已毕咱们暂时忽略。 天然查询很苟简,然则插入节点则略略勤劳,因为插入后,新节点与其父节点可能会违背小堆性质,因此在完成插入后,咱们还需使用上头已毕的左旋转或右旋转来进行营救。
|