二叉查找樹概念與相關(guān)leetcode題目

概念

二叉查找樹,也叫二叉搜索樹。樹中任意一個節(jié)點,該節(jié)點的左子樹中每個節(jié)點的值,都小于該節(jié)點的值;右子樹中每個節(jié)點的值,都大于該節(jié)點的值。

查找

從根節(jié)點開始查找,若查找的數(shù)據(jù)等于根節(jié)點的值,則返回;若查找的數(shù)據(jù)小于根節(jié)點的值,則在左子樹遞歸查找;若查找的數(shù)據(jù)大于根節(jié)點的值,則在右子樹遞歸查找。

插入

插入的數(shù)據(jù)一般會放置到葉子節(jié)點上,因此也是從根節(jié)點開始遍歷。

  • 如果插入的數(shù)據(jù)比節(jié)點的數(shù)據(jù)大,且節(jié)點的右子樹為空,那么直接將插入數(shù)據(jù)作為右子樹節(jié)點;如果不為空,則循環(huán)遍歷右子樹,查找插入位置。

  • 同理,如果插入的數(shù)據(jù)比節(jié)點數(shù)據(jù)小,且節(jié)點的左子樹為空,那么將插入數(shù)據(jù)作為左子樹節(jié)點;如果不為空,則循環(huán)遍歷左子樹,查找插入位置。

刪除

刪除二叉查找樹的操作分為三種情況:

一、刪除的節(jié)點沒有左右子樹,那么直接將父節(jié)點指向該刪除節(jié)點的指針,設(shè)置為null

二、刪除的節(jié)點有一個子節(jié)點,那么將父節(jié)點的指向刪除節(jié)點的指針,改為指向刪除節(jié)點的子節(jié)點

三、刪除的節(jié)點有兩個子節(jié)點,需要遍歷找到刪除節(jié)點的右子樹中最小的節(jié)點,將最小的節(jié)點替換到刪除節(jié)點上,最后將最小節(jié)點刪除

時間復(fù)雜度

時間復(fù)雜度和樹的高度成正比,即o(height)

一、最壞情況

若子節(jié)點都在某一側(cè),就會退化成鏈表,時間復(fù)雜度為o(n)

二、最穩(wěn)定情況

對于n個節(jié)點的完全二叉樹來說,樹的高度介于這兩者之間:

n >= 1+2+4+8+...+2^(L-2)+1

n <= 1+2+4+8+...+2(L-2)+2(L-1)

L 的范圍是[log2(n+1), log2n +1]。完全二叉樹的層數(shù)小于等于 log(2底數(shù)) n +1,也就是說,完全二叉樹的高度小于等于 log(2底數(shù)) n。

顯然,極度不平衡的二叉查找樹,它的查找性能肯定不能滿足我們的需求。我們需要構(gòu)建一種不管怎么刪除、插入數(shù)據(jù),在任何時候,都能保持任意節(jié)點左右子樹都比較平衡的二叉查找樹,因此衍生出一種特殊的二叉查找樹,平衡二叉查找樹。平衡二叉查找樹的高度接近 logn,所以插入、刪除、查找操作的時間復(fù)雜度也比較穩(wěn)定,是 O(logn)。

實戰(zhàn)題

leetcode 104題,如何求一顆二叉樹的高度


public int maxDepth(TreeNode root) {

if (root == null) return 0;

if (root.left == null && root.right == null) return 1;

int leftDepth = maxDepth(root.left);

int rightDepth = maxDepth(root.right);

return leftDepth >= rightDepth ? leftDepth + 1 : rightDepth + 1;

}

leetcode 450題,二叉查找樹的刪除操作


public TreeNode deleteNode(TreeNode root, int key) {

TreeNode del = root;

TreeNode delParent = null;

// 查找刪除節(jié)點

while (del != null) {

if (del.val == key) break;

if (key > del.val) {

delParent = del;

del = del.right;

} else {

delParent = del;

del = del.left;

}

}

if (del == null) return root;

// 若刪除節(jié)點的存在兩個子節(jié)點,找到右子樹的最小節(jié)點替換

if (del.left != null && del.right != null) {

TreeNode minDel = del.right;

TreeNode minDelParent = del;

while (minDel.left != null) {

minDelParent = minDel;

minDel = minDel.left;

}

del.val = minDel.val;

del = minDel;

delParent = minDelParent;

}

// 若刪除節(jié)點只存在一個子節(jié)點,或刪除節(jié)點沒有子節(jié)點

TreeNode child;

if (del.left != null) child = del.left;

else if (del.right != null) child = del.right;

else child = null;

// 刪除節(jié)點

if (delParent == null) return child;

else if (delParent.left == del) delParent.left = child;

else delParent.right = child;

return root;

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容