這是一道在 HackerRank 上的 SQL 競賽題,題目叫做「Binary Tree Nodes」,它的難度等級屬於中級。mysql
題目描述
給定一張表 BST,其中包含兩列:N 和 P,其中 N 表示二叉樹中節點的值,P 是 N 的父級。sql
Column | Type |
---|---|
N | Integer |
P | Integer |
編寫 SQL 以查找按節點值排序的二叉樹的節點類型。每一個節點只能屬於如下類型中的一種:微信
- Root:若是節點是根節點。
- Leaf:若是節點是葉節點。
- Inner:若是節點既不是根節點也不是葉節點。
輸入樣例.net
N | P |
---|---|
1 | 2 |
3 | 2 |
6 | 8 |
9 | 8 |
2 | 5 |
8 | 5 |
5 | null |
輸出結果code
1 Leaf 2 Inner 3 Leaf 5 Root 6 Leaf 8 Inner 9 Leaf
說明blog
下圖是示例數據構成的二叉樹:排序
解決方案
每一個節點的類型只能屬於 Root、Leaf、Inner 中的一種。Root 類型很好判斷,若是一個節點沒有父節點,那該節點就是跟節點,對應的類型就是 Root。若是一個節點沒有子節點,那麼它就是葉子節點,即爲 Leaf 類型。get
除了 Root 和 Leaf 類型的節點,剩下的就是 Inner 類型的節點。該如何判斷一個節點是否是 Inner 類型呢?table
能不能經過「存在子節點」這個條件判斷呢?不能!由於根節點也有子節點。class
那經過「存在父節點」這個條件判斷呢?也不能!由於葉子節點存在父節點。
顯然,這兩個條件的範圍都太大了,咱們適當加入一些限制條件就能夠用來判斷是否是 Inner 類型的節點了。「存在子節點且不爲根節點」和「存在父節點且不爲葉子節點」均可以用來做爲判斷節點是 Inner 類型的條件。
具體的 SQL(MySQL) 實現以下:
SELECT N, IF( P IS NULL, 'Root', IF ( (SELECT COUNT(*) FROM BST WHERE P = a.N) = 0, 'Leaf', 'Inner' ) ) FROM BST a ORDER BY N
本文分享自微信公衆號 - SQL實現(gh_684ee9235a26)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。