پشته با MULTIPOP (تحلیل سرشکن)
یک MULTIPOP ممکن است چند عضو را با هم بردارد و گران باشد، ولی هر عضو حداکثر یک بار برداشته میشود؛ پس هزینهی کل n عمل حداکثر 2n است.
پشتهای با سه عمل: PUSH(x)، POP و MULTIPOP(k) که حداکثر k عضو از بالا برمیدارد. یک MULTIPOP ممکن است O(n) هزینه داشته باشد، پس شاید فکر کنی n عمل O(n²) هزینه دارند.
- زمان:
O(1) amortized per operation - حافظه:
O(n) - CLRS، بخش ۱۶.۱
عددهای مثبت PUSH و منفیها MULTIPOP اند: شش PUSH، MULTIPOP(4)، دو PUSH و MULTIPOP(10). هزینهی کل ۱۶ برای ۱۰ عمل (۸ PUSH و ۸ pop)، کمتر از ۲ × ۱۰.
def multipop_stack(ops):# A positive number pushes itself; −k pops up to k items at once (0 pops nothing).stack = []cost = 0for op in ops:if op > 0:stack.append(op)cost = cost + 1else:k = -opwhile stack and k > 0:stack.pop()k = k - 1cost = cost + 1return cost
شروع اجرا
متغیرهای محلی
نارنجی = در همین گام عوض شد
ops list
Call stack
- multipop_stack()خط 1
توضیح
ایده
پشتهای با سه عمل: PUSH(x)، POP و MULTIPOP(k) که حداکثر k عضو از بالا برمیدارد. یک MULTIPOP ممکن است O(n) هزینه داشته باشد، پس شاید فکر کنی n عمل O(n²) هزینه دارند.
تحلیل سرشکن
هر عضو فقط یک بار push و حداکثر یک بار pop میشود. پس تعداد کل pop ها (حتی درون MULTIPOP ها) از تعداد push ها بیشتر نیست و هزینهی کل n عمل حداکثر 2n است: هر عمل بهطور سرشکن O(1).
روش پتانسیل: پتانسیل را تعداد عضوهای پشته بگیر. PUSH پتانسیل را یکی زیاد میکند (هزینهی سرشکن ۲)، و هر pop یک واحد پتانسیل خرج میکند (هزینهی سرشکن ۰).
ورودی
عددهای مثبت PUSH همان عدد و عدد منفی −k یعنی MULTIPOP(k).
در trace به چه چیزی نگاه کنی
- میلهها پشتهاند (بالای پشته سمت راست).
costدر پنل حافظه هزینهی کل تا اینجاست.