درخت آمارهی ترتیبی (OS-Select و OS-Rank)
درخت جستجویی که هر گره اندازهی زیردرختش را نگه میدارد؛ با آن، i-امین کوچکترین کلید و رتبهی هر کلید در O(h) پیدا میشود.
اگر هر گرهی درخت جستجو اندازهی زیردرختش (size) را هم نگه دارد، میتوانیم آمارههای ترتیبی را بدون پیمایش کل درخت پیدا کنیم. این یک نمونهی افزودن به ساختار داده (augmenting) است (CLRS فصل ۱۷).
- زمان:
O(h) - حافظه:
O(1) extra - CLRS، بخش ۱۷.۱
۱۲ کلید؛ پنجمین کوچکترین ۱۹ است و رتبهی ۳۸، ۱۰ است. عدد کوچک زیر هر گره اندازهی زیردرخت آن است.
class Node:def __init__(self, key):self.key = keyself.left = Noneself.right = Noneself.size = 1 # the number of nodes in this subtreedef os_tree(A, i, k):root = build(A[0])found = select(root, i)r = rank(root, k)return [found, r]def size(x):if x is None:return 0return x.sizedef select(x, i):# The i-th smallest key: the root of a subtree is its (size(left) + 1)-th smallest.while x is not None:r = size(x.left) + 1if i == r:return x.keyif i < r:x = x.leftelse:i = i - rx = x.rightreturn Nonedef rank(root, k):# How many keys are ≤ k: add up the left subtrees (and nodes) we pass on the way right.r = 0x = rootwhile x is not None:if k < x.key:x = x.leftelif k > x.key:r = r + size(x.left) + 1x = x.rightelse:r = r + size(x.left) + 1return rreturn Nonedef build(keys):# An ordinary search tree, with each node's size updated on the way down.root = Nonefor key in keys:node = Node(key)if root is None:root = nodecontinuep = rootwhile True:p.size = p.size + 1if key < p.key:if p.left is None:p.left = nodebreakp = p.leftelse:if p.right is None:p.right = nodebreakp = p.rightreturn root
شروع اجرا
∅
متغیرهای محلی
نارنجی = در همین گام عوض شد
A list
Call stack
- os_tree()خط 9
توضیح
ایده
اگر هر گرهی درخت جستجو اندازهی زیردرختش (size) را هم نگه دارد، میتوانیم آمارههای ترتیبی را بدون پیمایش کل درخت پیدا کنیم. این یک نمونهی افزودن به ساختار داده (augmenting) است (CLRS فصل ۱۷).
OS-SELECT(x, i)
ریشهی هر زیردرخت، size(left) + 1-امین کوچکترین کلید آن است. اگر i همین است، جواب ریشه است؛ اگر کمتر است به چپ برو؛ وگرنه به راست برو و دنبال (i − r)-امین بگرد.
OS-RANK(k)
رتبهی k تعداد کلیدهای کمتر یا مساوی آن است. از ریشه تا k پایین میرویم و هر بار که به راست میرویم، گره و زیردرخت چپش را میشماریم.
نگه داشتن اندازهها
در درج، اندازهی گرههای مسیر یکی زیاد میشود؛ در چرخشها (درخت قرمز-سیاه) فقط اندازهی دو گره عوض میشود. پس با درخت متوازن همهی عملها O(log n) میمانند.
ورودی
A ترتیب درج کلیدها، i رتبهای که میخواهیم و k کلیدی که رتبهاش را میخواهیم.