前言:前序/中序線索二叉樹尋找后繼結點代碼的筆記
前序線索二叉樹尋找后繼
前驅有很多種情況,太麻煩,自己這里就不寫了,因為尋找前驅結點的話,不可能是在當前結點的下面的,因為前序是根左右,左右結點只有可能是后繼結點,想要找到該結點的前驅結點就需要先拿到父節點,然后再進行操作,這里只能相關的情況放在這里,就不實現了
這里的前序線索二叉樹只實現后繼結點的尋找,如下所示
在前序線索二叉樹中尋找后繼就兩種簡單的情況,因為前序遍歷是根左右
1、第一種情況當要尋找結點P的左子樹存在的時候,那么結點P的左節點就是當前結點P的后繼結點
2、第二種情況當要尋找結點P的左子樹不存在,右子樹存在的時候,那么結點P的后繼結點就是當前結點P的右節點
3、第三種情況當要尋找結點P的左右子樹都不存在,那么結點P就是單結點
上面的三種都是不是葉子結點的時候,如果是葉子結點的話,又因為是線索二叉樹,所以對於葉子結點的話直接通過右結點就可以直接找到了
// 中序的后繼結點
// 前序后繼結點尋找
TreeNode* getAfterNodeFromPre(TreeNode* pTreeNode)
{
// 直接是葉子結點的情況,那么葉子結點的右子樹pRightTreeNode就直接是要找的后繼結點
if (pTreeNode->pLeftTreeNode != NULL && pTreeNode->iRightFlag == 1)
return pTreeNode->pRightTreeNode;
// 要找的pTreeNode結點有左孩子,那么該左孩子就是要找的后繼結點
if (pTreeNode->pLeftTreeNode != NULL)
return pTreeNode->pLeftTreeNode;
// 要找的pTreeNode結點沒有左孩子,但是有右孩子,那么該右孩子就是P結點要找的后繼結點
if (pTreeNode->pLeftTreeNode == NULL && pTreeNode->pRightTreeNode)
return pTreeNode->pRightTreeNode;
// 都不滿足的話,那當前的結點就是根節點,並且結點數只有一個
return NULL;
}
中序線索二叉樹尋找前驅后繼結點
中序比較簡單,只有一種情況,要找的結點的后繼結點就是該結點的右子數中最左下的結點,所以直接一個遞歸就可以進行解決了
需要注意的就是因為是線索二叉樹,所以主要不設置Flag條件的話,那么就會造成死循環,因為找的是前驅和后繼結點,所以這兩個結點
// 獲取中序后繼結點遞歸函數
// 中序的后繼結點是當前右子樹最左下的結點
TreeNode* getAfterNodeFromMiddle(TreeNode* pTreeNode)
{
if (pTreeNode->pLeftTreeNode != NULL && pTreeNode->iLeftFlag == 0)
return getAfterNodeFromMiddle(pTreeNode->pLeftTreeNode);
else
return pTreeNode;
}
// 獲取中序后繼結點遞歸函數
// 中序的前驅結點是當前左子樹最右下的結點
TreeNode* getPreNodeFromMiddle(TreeNode* pTreeNode)
{
if (pTreeNode->pRightTreeNode != NULL && pTreeNode->iRightFlag == 0)
return getPreNodeFromMiddle(pTreeNode->pRightTreeNode);
else
return pTreeNode;
}
// 尋找中序后續結點大函數
TreeNode* findMiddleAfterTreeNode(TreeNode* pTreeNode)
{
// 如果iRightFlag為1的話,那么當前的結點的右節點就是當前結點的后繼結點
if (pTreeNode->iRightFlag == 1)
return pTreeNode->pRightTreeNode;
return getAfterNodeFromMiddle(pTreeNode->pRightTreeNode);
}
// 尋找中序后續結點大函數
TreeNode* findMiddlePreTreeNode(TreeNode* pTreeNode)
{
if (pTreeNode->iLeftFlag == 1)
return pTreeNode->pLeftTreeNode;
return getPreNodeFromMiddle(pTreeNode->pLeftTreeNode);
}
后序線索二叉樹尋找前驅
X