干货版《算法导论》18:遍历增删原理、时间复杂度与集合序列实现全解
干货çãç®æ³å¯¼è®ºã18ï¼éåå¢å åçãæ¶é´å¤æåº¦ä¸éååºåå®ç°å ¨è§£
软件ç§å¦_éå¦è 2026-08-21 0 é 读9åéð³ åè¨å¯¼è¯»
æ°æ®ç»æä¹å¢ï¼æ°ç»ä»¥çº¿æ§è§æ´ç«è¶³ï¼å´å°äºå¨æè¿ä»£çä½ææ¡æ¢ï¼äºåæ 以å±çº§åµå¥æå½¢ï¼åçµæ´»çææç»æãä¼å¼çæ¶é´å¤æåº¦ï¼æä¸ºç®æ³å·¥ç¨çæ ¸å¿åºç³ðã纵è§åç±»æ°æ®ç»æéåï¼éæåå¨å®ç¨æ°ç»ï¼å¨æå¢å ãæåºæ£ç´¢ãåºåç»´æ¤çé«é¢åºæ¯ï¼äºåæ å§ç»æ¯æä¼è§£ä¹ä¸ã
æ¬æå°æ·±åº¦æè§£äºåæ æ ¸å¿è¿ç®é»è¾ï¼æ¶µçå ¨å±æ¶é´å¤æåº¦åæãèç¹æå ¥/å é¤ååºæ¯åçãå驱åç»§æ£ç´¢æºå¶ãæ ç»æå®ç°éåä¸åºååå¤§æ ¸å¿æ¨¡åï¼æé éä¿åçæ¨æ¼ãè§æ´ä»£ç 示ä¾ãæ§è½å¯¹æ¯åæï¼å ¨æ¹ä½åéäºåæ åºå±é»è¾ï¼éé ç®æ³å·é¢ãå·¥ç¨å¼åãåºå±æ¶æå¦ä¹ å ¨åºæ¯â ã
Bilibili 忥è§é¢
干货çãç®æ³å¯¼è®ºã18ï¼éåå¢å åçãæ¶é´å¤æåº¦ä¸éååºåå®ç°å ¨è§£
ä¸ãäºåæ æ ¸å¿è¿ç®ï¼æ¶é´å¤æåº¦æ·±åº¦è§£æ â±ï¸
1.1 å ¨å±å¤æåº¦æ ¸å¿è§å¾
äºåæ ææåºç¡è¿ç®ï¼éåãå驱åç»§æ¥è¯¢ãèç¹å¢å ï¼ï¼ç»ä¸æåæ¶é´å¤æåº¦ä¸º O(H)ï¼H 为äºåæ é«åº¦ï¼ðãæ¤è§å¾è´¯ç©¿å ¨ææææä½ï¼æ¯äºåæ æ§è½ä¼å¿çæ ¸å¿æ ¹æºã
ä¸é´ç®æ³ï¼å¯å¿«ä¸ç ´ãå½äºåæ è¶è¿å¹³è¡¡ç¶ææ¶ï¼æ é« HapproxlognH approx log nHapproxlognï¼æ¤æ¶ææè¿ç®è¿ä¹ç¬æ¶å®æï¼æç碾å线æ§ç»æï¼è¥æ éå为é¾å¼ç»æï¼H=nH = nH=nï¼å¤æåº¦éè³ O(n)ï¼æ§è½å£å¿å¸æ¾ãè¿ä¹æ¯å¹³è¡¡äºåæ ãçº¢é»æ çè¿é¶ç»æç设计åè¡·ââä¸¥æ§æ é«ï¼ç¨³å®æ§è½ã
1.2 æ ç»æ VS æ°ç»ç»æï¼æ§è½ç»´åº¦ç»æå¯¹æ¯
æ°ç»ä¾æè¿ç»å åï¼è¯»åé度ä¼å¼ï¼ä½å¨å¨æç»´æ¤æåºéååºååºæ¯ä¸åå¨è´å½çæ¿ï¼æ¯æ¬¡å¢å å ç´ åé平移åç»æ°æ®ï¼åºå®äº§ç O(n) çº¿æ§æ¶é´å¼éï¼æ°æ®éè¶å¤§ï¼æ§è½è¡°åè¶å§çâã
åè§äºåæ ï¼ä¾æææå±çº§ç¹æ§ï¼æ éå ¨å±ç»´æ¤æåºåºåï¼ä» éè¿å±é¨èç¹æéè°æ´å³å¯å®æè¿ä»£ã以 O(H) 对æ°çº§å¤æåº¦ï¼æ¿ä»£æ°ç» O(n) 线æ§å¤æåº¦ï¼æµ·éæ°æ®å¨ææ´æ°åºæ¯ä¸ï¼æ§è½å·®è·åææ°çº§æå¼ð¥ã
1.3 å驱/åç»§æ£ç´¢å¤æåº¦
æ¥æ¾æå®èç¹çå驱ï¼éååºåä¸ååºèç¹ï¼ãåç»§ï¼éååºåä¸ååºèç¹ï¼ï¼é»è¾ç®æ´ä¸æ§è½ç¨³å®ãè½é¨ååºæ¯å¯æåç»æ¢éåãèçè¿ç®èæ¶ï¼ä½ç®æ³æåå¤æåº¦ä»ä¸¥æ ¼éµå¾ª O(H)ï¼æ ä¾å¤ãæ ä¼åæ·å¾ï¼å¤æåº¦è¾¹çæ¸ æ°å¯æ§ã
äºãäºåæ èç¹æå ¥ï¼ååºæ¯åç+代ç å®ç° ð»
äºåæ èç¹æå ¥æ ¸å¿å为ãç®æ èç¹æ å³åæ ããç®æ èç¹åå¨å³åæ ãä¸¤å¤§å¯¹ç§°åºæ¯ï¼æ´ä½éµå¾ªå æ£ç´¢åç»§ãå常éæå ¥çé»è¾ï¼æ ¸å¿èæ¶éä¸äºåç»§æ¥è¯¢ï¼æå ¥å¨ä½æ¬èº«æ é¢å¤å¼éã
2.1 æå ¥æ ¸å¿è§åï¼åæé»è¾ï¼åæå¯¹ç§°å¯æ¨ï¼
-
åºæ¯ä¸ï¼ç®æ èç¹æ å³åæ â é»è¾æç®ï¼ç´æ¥å°æ°èç¹æè½½ä¸ºç®æ èç¹çå³åèç¹å³å¯ãæ ééååæ ãæ éè°æ´ææç»æï¼å次æéèµå¼å®ææå ¥ï¼æ¶é´å¤æåº¦ O(1)ã
-
åºæ¯äºï¼ç®æ èç¹åå¨å³åæ â éå æ£ç´¢ç®æ èç¹çåç»§èç¹ï¼å³åæ çæå·¦ååèç¹ï¼ï¼è¯¥èç¹å¤©ç¶æ å·¦åæ ï¼åå°æ°èç¹æè½½ä¸ºè¯¥åç»§èç¹çå·¦åèç¹ã æ ¸å¿åçï¼åç»§èç¹ç±ãå³ç§»ä¸æ¬¡ã左移å°åºãè§åçæï¼å¿ ç¶ç©ºç½®å·¦åæ ï¼ä¸ºæ°èç¹é¢çå¯ä¸åæ³æå ¥ä½ï¼å®ç¾ç»´ç³»ä¸åºéåæåºæ§ã
2.2 宿´å¯è¿è¡ä»£ç 示ä¾ï¼Pythonï¼
# å®ä¹äºåæ èç¹ç»æ
class TreeNode:
def __init__(self, val):
self.val = val
self.left = None
self.right = None
self.parent = None
# æ¥æ¾èç¹çåç»§èç¹ O(H)
def find_successor(node: TreeNode) -> TreeNode:
# åå¨å³åæ ï¼åå³åæ æå·¦èç¹
if node.right:
cur = node.right
while cur.left:
cur = cur.left
return cur
# æ å³åæ ï¼åä¸åæº¯ï¼æ¬ææå
¥åºæ¯æ 鿤忝ï¼
cur = node
while cur.parent and cur == cur.parent.right:
cur = cur.parent
return cur.parent
# èç¹åææ ¸å¿é»è¾
def insert_after(target_node: TreeNode, new_node: TreeNode):
"""å¨ç®æ èç¹åæå
¥æ°èç¹ï¼æ»å¤æåº¦O(H)"""
if not target_node.right:
# åºæ¯1ï¼æ å³åæ ï¼ç´æ¥æè½½å³åèç¹
target_node.right = new_node
new_node.parent = target_node
else:
# åºæ¯2ï¼åå¨å³åæ ï¼æ¾åç»§èç¹æè½½å·¦åèç¹
successor = find_successor(target_node)
successor.left = new_node
new_node.parent = successor
# æ§è½è¯´æï¼åç»§æ¥è¯¢O(H)ï¼æå
¥èµå¼O(1)ï¼æ´ä½å¤æåº¦ç¨³å®O(H)
2.3 æå ¥æ§è½æ·±åº¦æ»ç»
纵è§å ¨æµç¨ï¼æå ¥æä½çæ§è½ç¶é¢ä» 为åç»§èç¹æ£ç´¢ï¼O(H)ï¼ï¼æéä¿®æ¹ãèç¹æè½½å为常é级è¿ç®ãæ è®ºæ°æ®è§æ¨¡å¦ä½å¢é¿ï¼ä» 䏿 é«ç¸å ³ï¼å½»åºè§é¿æ°ç»çº¿æ§å¹³ç§»çæ§è½ç¼ºé·ï¼éé é«é¢å¨ææå ¥åºæ¯ðã
ä¸ãäºåæ èç¹å é¤ï¼éå½ç½®æ¢åç+è¾¹çå¤ç ð ï¸
èç¹å é¤ç¸è¾æå ¥æ´ä¸ºå¤æï¼æ ¸å¿é¾ç¹å¨äºç»´æäºåæ ææè¿éæ§ä¸éåæåºæ§ãç®æ³æãå¶åèç¹ãéå¶åèç¹ãå维度æåï¼éè¿å驱/åç»§èç¹å¼ç½®æ¢+éå½å é¤ï¼å®ç°é¶ç§©åºéä¹±ç髿å é¤ã
3.1 å 餿 ¸å¿åºæ¯è§å
-
åºæ¯ä¸ï¼å¶åèç¹å é¤ ð æç®è¾¹çåºæ¯ï¼æ é夿éåï¼ä» éåæç¶èç¹ä¸å½åå¶åèç¹çæéå ³èï¼ç´æ¥éæ¾èç¹å³å¯ãæ ææè°æ´ãæ ç§©åºæ°å¨ï¼æ¶é´å¤æåº¦ O(1)ã
-
åºæ¯äºï¼éå¶åèç¹å é¤ ð¥ æ ¸å¿æ ¸å¿é»è¾ï¼ä¸ç´æ¥å é¤å½åèç¹ï¼éè¿å¼ç½®æ¢è½¬ç§»å é¤ååã
- è¥å½åèç¹åå¨å·¦åæ ï¼å¹é å·¦åæ æå³èç¹ï¼å驱èç¹ï¼ï¼äº¤æ¢ä¸¤èç¹åå¨å¼ï¼éå½å é¤å驱èç¹ï¼
- è¥å½åèç¹æ å·¦åæ ãä» åå³åæ ï¼å¹é å³åæ æå·¦èç¹ï¼åç»§èç¹ï¼ï¼äº¤æ¢ä¸¤èç¹åå¨å¼ï¼éå½å é¤åç»§èç¹ã æ ¸å¿ä¼å¿ï¼æ¯æ¬¡éå½ååæ åºå±æ¨è¿ï¼æç»æ¶æè³å¶åèç¹å®æå é¤ï¼å ¨ç¨æ é«å¯æ§ã
3.2 宿´å é¤ä»£ç 示ä¾ï¼Pythonï¼
# æ¥æ¾èç¹çå驱èç¹ O(H)
def find_predecessor(node: TreeNode) -> TreeNode:
if node.left:
cur = node.left
while cur.right:
cur = cur.right
return cur
cur = node
while cur.parent and cur == cur.parent.left:
cur = cur.parent
return cur.parent
# éå½å é¤èç¹ï¼ç»´ææ ç»ææåº
def delete_node(root: TreeNode, target: TreeNode) -> TreeNode:
# åºæ¯1ï¼å é¤å¶åèç¹
if not target.left and not target.right:
if target.parent:
if target.parent.left == target:
target.parent.left = None
else:
target.parent.right = None
return None
# åºæ¯2ï¼å é¤éå¶åèç¹
if target.left:
# åå¨å·¦åæ ï¼ç½®æ¢å驱èç¹å¹¶éå½å é¤
pred = find_predecessor(target)
target.val = pred.val
delete_node(root, pred)
else:
# æ å·¦åæ ï¼ç½®æ¢åç»§èç¹å¹¶éå½å é¤
succ = find_successor(target)
target.val = succ.val
delete_node(root, succ)
return root
# æ§è½è¯´æï¼é彿·±åº¦çäºæ é«Hï¼æ»å¤æåº¦ä¸¥æ ¼O(H)
3.3 å 餿§è½æ ¸å¿è§£è¯»
ææå 餿ä½çéå½è·¯å¾åèªä¸èä¸ãéå±åä¸ï¼è¿ç®æ»éä¸¥æ ¼ä¸æ é« H ææ£æ¯ï¼æåå¤æåº¦ç¨³å® O(H)ãç®æ³å·§å¦è§é¿äºç´æ¥å é¤éå¶åèç¹å¯¼è´çæ æè£é®é¢ï¼éè¿ãå¼ç½®æ¢ãå åºå±ãçæ ¸å¿ææ³ï¼ä»¥æå°æææ¹å¨ç»´ç³»å ¨å±æåºæ§ï¼æ¯äºåæ 髿è¿ä»£çæ ¸å¿ç²¾é«â¨ã
åãäºåæ é«é¶åºç¨ï¼éåä¸åºåçåºå±å®ç° ð¯
äºåæ çæ ¸å¿å·¥ç¨ä»·å¼ï¼ä¸æ¢äºåºç¡å¢å æ¥æ¹ï¼æ´å¯éè¿èªå®ä¹éåç§©åºï¼ç²¾åå®ç°éåï¼Setï¼ä¸åºåï¼Sequenceï¼ä¸¤å¤§æ ¸å¿æ°æ®ç»æï¼åºå±é»è¾ç®æ´ãæ§è½ä¼å¿æ¾èã
4.1 æåºéåï¼Setï¼å®ç°æ¹æ¡
便äºåæç´¢æ ï¼BSTï¼æ ¸å¿æ§è´¨å®ç°ï¼ä»»æèç¹ï¼å·¦åæ ææèç¹å¼ < å½åèç¹å¼ < å³åæ ææèç¹å¼ï¼éå½éé æ´æ ææèç¹ðã
åºäºè¯¥ç¹æ§ï¼åªéå°äºåæ ä¸åºéåç§©åºï¼è®¾ç½®ä¸ºé®å¼é墿åºç§©åºï¼å³å¯å¤©ç¶å®ç°æ éå¤ãæåºçéåç»æã便 O(H) 级å«çå¢å æ¥å¤æåº¦ï¼å®èåå¸éåçæ åºç¼ºé·ãæåºæ°ç»ç使è¿ä»£ç¼ºé·ã
4.2 èªå®ä¹åºåï¼Sequenceï¼å®ç°æ¹æ¡
åºåæ éé®å¼æåºçº¦æï¼é»è¾æ´ä¸ºçµæ´»ï¼ç´æ¥å°äºåæ çä¸åºéå顺åºï¼å®å ¨å¯¹é½ä¸å¡æéçåºå顺åºå³å¯ã
å¼åè å¯èªç±å®ä¹èç¹æåé»è¾ï¼éè¿åæçæå ¥ãå 餿ä½ï¼çµæ´»è°æ´åºååå顺åºï¼å®ç°å¨æåºåçé«æç»´æ¤ï¼éé é¾è¡¨ãæåºéåçåºæ¯çåºå±ä¼åã
4.3 ç²¾åæ£ç´¢ä¸æ¨¡ç³æ£ç´¢å®ç°
-
ç²¾åé®å¼æ£ç´¢ ðï¼å®å ¨å¤ç¨äºåæç´¢æ äºåé»è¾ï¼ä»æ ¹èç¹åºåï¼é®å¼åå°åéåå·¦åæ ãé®å¼å大åéåå³åæ ï¼å次æ£ç´¢å¤æåº¦ O(H)ï¼çä»·äºäºåæ¥æ¾æçã
-
模ç³é»è¿æ£ç´¢ ðï¼ä¾æå驱ãåç»§èç¹å®ç°ãæ¥è¯¢ãåä¸ä¸ªèç¹ã峿¾å½åèç¹åé©±ï¼æ¥è¯¢ãåä¸ä¸ªèç¹ã峿¾å½åèç¹åç»§ï¼å®ç¾æ¯æåºé´æ¥è¯¢ãé»è¿å¹é çé«é¶ä¸å¡åºæ¯ã
äºãå ¨ææ ¸å¿æ»ç» & ææ¯å±æ ð
ð² æ ¸å¿è§å¾å¤ç
-
å¤æåº¦ç»ä¸ï¼äºåæ éåãå驱åç»§æ¥è¯¢ãå¢å æä½ï¼æåå¤æåº¦å为 O(H)ï¼å¹³è¡¡æ ç¶æä¸è¶è¿å¯¹æ°çº§é«æï¼
-
å¢å æ ¸å¿é»è¾ï¼æå ¥åææ å³åæ ååºæ¯ï¼åç½®æ¥è¯¢ã常éæå ¥ï¼å é¤ä¾æå驱åç»§ç½®æ¢ï¼æ¶æè³å¶åèç¹æä½ï¼è§é¿æææè£ï¼
-
é«é¶è½å°è½åï¼éè¿éåç§©åºèªå®ä¹ï¼å¯é«æå®ç°æåºéåä¸å¨æåºåï¼æ¯æç²¾å/模ç³ä¸¤ç±»æ£ç´¢åºæ¯ã
ð ææ¯å±æ
æ¬æèç¦æ®éäºåæ æ ¸å¿åçä¸åºç¡åºç¨ï¼æªæ·±å ¥æ é«å¹³è¡¡ä¼åãåç»å¯åºäºæ¬æé»è¾ï¼å»¶ä¼¸å¦ä¹ 平衡äºåæ ãçº¢é»æ ãAVLæ ï¼éè¿äººå·¥å¹²é¢æ é«ï¼å½»åºè§é¿é¾å¼éåé®é¢ï¼å°æ§è½ç¨³å®ç»´æå¨ O(logn)O(log n)O(logn)ï¼éé å·¥ä¸çº§é«æ§è½å¼ååºæ¯ã
è¥éè½å°å¤æåºåå¨æç»´æ¤ãæµ·éæ°æ®æåºè¿ä»£åºæ¯ï¼äºåæ ä½ç³»æ°¸è¿æ¯æä¼åºå±éåä¹ä¸ð¯ï¼
Aitishiku.com