contributed by <Shiritai
>
AAAA
考慮對齊,取得親代指標long
(64 bits) 對齊,由於每個地址指向一 byte (8 bits),故真正對齊的地址需為 的倍數,也就是最低 位元應為零。long
在不同 ABI 下長度不一,此時可以利用 sizeof
處理跨平台的情況。
BBBB
設定顏色為紅色CCCC
設定顏色為黑色DDDD
、EEEE
走訪左右子樹,當非走訪至葉節點且與當前節點相比較小/大時,往左/右子節點走訪。
cmap
list
list
末個 next
設為 NULL
後,重設間接指標的起點。
以中序遍歷重建 list
,為例,其使用間接指標的技巧,避免邊界條件判斷的必要。假設從 a 走訪到 c,行為如下圖所示:
*list = node (1), list = &(*list)->next
*list = node (2), list = &(*list)->next
*list = node (3), list = &(*list)->next
next
設為 NULL
取親代指標的邏輯與測驗一同理,利用 sizeof 完成跨平台的指標對齊。
取顏色直接取最低兩位元即可,之所以是兩位元是因為平衡因子有 0
, 1
, 2
三種可能,佔 bits。
parent_balance
成員為其指派親代節點指標可利用之前實作的 avl_balance
函式保留平衡因子的部分:
指派平衡因子時同理可複用之前實作過的 avl_parent
函式來保留親代指標的部分:
旋轉比較難畫,就直接引用維基百科的圖了。
觀察 MMMM
, NNNN
所在之迴圈中較前面,針對 RR/RL 所執行的左旋轉/右旋後左旋,推斷 MMMM
和 NNNN
為處理 LL/LR 的情況,故為對應的右旋轉/左旋後右旋,實作如下:
TODO
以下程式碼應實現 。
觀察程式碼,由其行為可見當 x
大於某二的冪長度之全一時,便以 shift
蒐集某長度之全一的長度,記錄 shift
於 r
後將 x
位移 shift
。從 個 開始,推測最後會處理一個 1 的情況,故我們應該看到:
上述程式碼對 x
的操作沒有必要,因為後續不再使用,故 (不考慮註解的) 第 3 行可去除,並可將 1, 2, 3 行簡化為:
至於 r
紀錄了什麼?當 x
為無號最大值 (全一) 時,shift
一路下來捕獲了 ,並將其以 or 運算紀錄於 r
,結果為 ,與 差一,由此認為 return (KKKK) + 1;
的 + 1
因此出現。
這樣一來 KKKK
為何就比較明朗了。考慮前方簡化版邏輯,由於直接回傳,不需要將結果存入 r
,故改為 expression 版如下:
再來我們簡化 x > 0x1
的部分。由於我們已經使用 這幾把拿來左移的尺,對於 位元的數字而言只可能還沒碰到原本最高的兩位,此時 x
只剩 這四種可能,故可替換其邏輯為 x >> 1
,捕獲未觸碰的原最高位。
所以答案為
KKKK = r | shift | x >> 1