برعکس کردن لیست پیوندی
جهت همهی پیوندهای لیست را با سه اشارهگر prev، cur و nxt یکییکی برمیگرداند؛ در یک گذر و بدون حافظهی اضافه.
لیست را از اول پیمایش میکنیم و پیوند هر گره را به گرهی قبلی برمیگردانیم. سه اشارهگر لازم است:
ادامهی توضیح ↓- زمان:
O(n) - حافظه:
O(1) - هوروویتز–ساهنی، فصل ۴
۱ → ۲ → ۳ → ۴ → ۵ برعکس میشود: ۵ → ۴ → ۳ → ۲ → ۱.
class Node:def __init__(self, val):self.val = valself.next = Nonedef reverse_list(items):head = Nonefor x in reversed(items):node = Node(x)node.next = headhead = node# prev: the part already reversed; cur: the part still to do.prev, cur = None, headwhile cur is not None:nxt = cur.nextcur.next = prevprev = curcur = nxthead = prevout = []while head is not None:out.append(head.val)head = head.nextreturn out
شروع اجرا
prevتهی
curتهی
متغیرهای محلی
نارنجی = در همین گام عوض شد
items list
12345
Call stack
- reverse_list()خط 7
گام ۱ از ۸۴
توضیح
ایده
لیست را از اول پیمایش میکنیم و پیوند هر گره را به گرهی قبلی برمیگردانیم. سه اشارهگر لازم است:
prev: سر بخشی که تا اینجا برعکس شده،cur: گرهای که الان پیوندش برمیگردد،nxt: گرهی بعدی، که باید قبل از برگرداندن پیوند ذخیره شود، وگرنه بقیهی لیست گم میشود.
در پایان prev سر لیست برعکسشده است.
هزینه
یک گذر و چند اشارهگر: زمان O(n) و حافظهی O(1). هیچ گرهای کپی یا جابهجا نمیشود.
در trace به چه چیزی نگاه کنی
- دو لیست کشیده شده: از
prev(بخش برعکسشده) و ازcur(بخش باقیمانده)؛ با هر گام یک گره از دومی به اولی میرود.