前驅節點
前驅節點的值小於該節點的值,是該節點左子樹中值最大的
后繼節點
后繼節點的值大於該節點的值,是該節點右子樹中值最小的
因為二叉搜索樹的中序遍歷出來的結果就是一棵樹節點上的值的升序排序,所以一個數的前驅節點的值就是比它小一個的數,后繼節點的值就是比它大一個的節點
找前驅節點有以下情況:
(1) 該節點有左子樹,那么該節點的前驅節點就是其左子樹中最大的那個。例如 10 它有左孩子,它的前驅節點就是左孩子中最大的也就是 8 。
(2) 該節點沒有左子樹,那么就又有兩種情況: 1. 該節點是其父節點的右孩子,那么它的前驅就是他的父節點; 例如 17 它的前驅就是16
2. 該節點是其父節點的左孩子,那么就得往其祖輩尋找直到找到它祖輩是左孩子為止,如果沒找到,那么說明該節點沒有前驅節點。 例如 8 它是左孩子,所以它的前驅不是它的父親,就得往上找,
而它的父親是他爺爺的右孩子,所以 8 的前驅就應該是它的爺爺 7 。
找后繼節點有以下情況:
(1) 該節點有右子樹,那么該節點的后繼節點就是其右子樹中最小的那個。例如 10 它有右子樹 它的后繼就是右子樹中最小的那個 14 。
(2) 該節點沒有右子樹,那么它的后繼節點也要往祖輩里面找,也是分兩種情況 : 1. 該節點是其父節點的左子樹,那么它的后繼節點就是他的父親; 2. 該節點是父節點的左子樹,
那么往上找,直到找到該節點的祖輩是左孩子為止,如果找不到,那么該節點沒有后繼節點。例如圖中的 17 它是父親的右孩子,往上找,發現它父親也是它爺爺的右孩子,而它爺爺沒有父輩了,所以該節點沒有后繼。
具體java實現的代碼如下:
1 /** 2 * 找給定節點的后繼節點 3 * @param node 給定樹中的節點 4 * @return 返回該節點存在中序遍歷順序下的后繼節點,有則返回后繼節點,無則返回null 5 * 6 */ 7 public TreeNode successor(TreeNode node){ 8 if(node==null){ return null;} 9 //若該節點的右子樹不為空,則后繼節點就是右子樹中的最小關鍵字節點 10 if(node.rightChild!=null){ 11 try { 12 return minElemNode(node.rightChild); 13 } catch (Exception e) { 14 e.printStackTrace(); 15 } 16 } 17 //若該節點右子樹為空 18 TreeNode parentNode=node.parent; 19 while(parentNode !=null && node==parentNode.rightChild){ 20 node=parentNode; 21 parentNode=parentNode.parent; 22 } 23 return parentNode; 24 } 25 26 /** 27 * 找出給定節點的后繼節點 28 * @param node 給定節點 29 * @return 后繼節點 30 */ 31 public TreeNode precessor(TreeNode node) throws Exception { 32 if(node==null){ return null;} 33 //若該節點有左子樹,則前驅節點就是左子樹中最大的那個 34 if(node.leftChild!=null){return maxElemNode(node.leftChild);} 35 //若該節點沒有左子樹 36 TreeNode parentNode=node.parent; 37 if(parentNode!=null&&node==parentNode.leftChild){ 38 node=parentNode; 39 parentNode=parentNode.parent; 40 } 41 return parentNode; 42 }