面試題之二叉搜尋樹的中位元

來源:互聯網
上載者:User

這個問題不算是很常見的問題,基本上在中文的論壇社區沒有看到過,遇見這個是因為偶爾在http://www.ocf.berkeley.edu/~wwu/cgi-bin/yabb/YaBB.cgi
上面註冊了帳號而看到的,題目如下:



Given a BST (Binary search Tree) how will you find median in that?
 
Constraints:
 
* No extra memory.
* Function should be reentrant (No static, global variables allowed.)
* Median for even no of nodes will be the average of 2 middle elements and for odd no of terms will be middle element only.
* Algorithm should be efficient in terms of complexity. 



中文不需要贅述了,就是二叉搜尋樹如何高效地找到中位元,不希望申請記憶體,不要static/global的變數來實現。

第一反應就是中序遍曆就是排序了,但是如果要計數的話,我們需要一個額外的變數,這樣恐怕需要或是靜態或者全域變數了,故不可以用。但是我們其他很多次都碰到了那樣類似的問題,如何把一個二叉樹原地轉化成雙向鏈表,那時候還有點覺得題目沒意思,沒啥用處。但是在這裡,作用得以體現。假如有形如

 

                                            10
                                          /    /
                                        6       14
                                      /  /     /  /
                                    4     8  12    16

的二叉樹轉化成了4=6=8=10=12=14=16這樣一個雙鏈表,那後面的問題就變成了如何在4=6=8=10=12=14=16裡面找到中間節點了,這對於我們習慣了2個快慢指標追趕的小朋友來說不算問題了。

下面就是寫的一個實現:

#include <iostream><br />typedef struct bstNode<br />{</p><p>int data;<br />bstNode* pLeft;<br />bstNode* pRight;</p><p>bstNode()<br />{<br />data = 0;<br />pLeft = NULL;<br />pRight = NULL;<br />}<br />}bstNode;<br />void bst2dll (bstNode* pNode, bstNode*& pTail )<br />{<br />// in-order traverse<br />if (pNode == NULL) return ;</p><p>if (pNode->pLeft) bst2dll(pNode->pLeft,pTail);</p><p>bstNode* pCurrent = pNode;<br />pCurrent->pLeft = pTail;<br />if (pTail)<br />pTail->pRight = pCurrent;<br />pTail = pCurrent;<br />if(pNode->pRight) bst2dll(pNode->pRight, pTail);<br />}<br />// parameter is the original root<br />// return the new double linked list head<br />int medianInBST ( bstNode* pRoot )<br />{<br />bstNode* pTail = NULL;<br />bst2dll(pRoot,pTail);</p><p>// dummy handling here<br />if (pTail == NULL) return -1;<br />bstNode* pFast = pTail;<br />bstNode* pSlow = pTail;</p><p>while (pFast&&pSlow)<br />{<br />if (pFast->pLeft==NULL)<br />return pSlow->data;<br />else if (pFast->pLeft != NULL && pFast->pLeft->pLeft == NULL)<br />return (pSlow->data + pSlow->pLeft->data)>>1;<br />else<br />{<br />pFast = pFast->pLeft;<br />pFast = pFast->pLeft;<br />pSlow = pSlow->pLeft;<br />}<br />}<br />}<br />// test case<br />/*<br /> 10<br />/ /<br /> 6 14<br /> / / / /<br /> 4 8 12 16<br />*/<br />bstNode* buildupTree()<br />{<br />// level 1<br />bstNode* pRoot = new bstNode;<br />pRoot->data = 10;<br />//level2<br />bstNode* pNewL = new bstNode;<br />pNewL->data = 6;<br />bstNode* pNewR = new bstNode;<br />pNewR->data = 14;<br />//level3<br />bstNode* pNewLL = new bstNode;<br />pNewLL->data = 4;<br />bstNode* pNewLR = new bstNode;<br />pNewLR->data = 8;<br />bstNode* pNewRL = new bstNode;<br />pNewRL->data = 12;<br />bstNode* pNewRR = new bstNode;<br />pNewRR->data = 16;</p><p>pRoot->pLeft = pNewL;<br />pRoot->pRight = pNewR;<br />pNewL->pLeft = pNewLL;<br />pNewL->pRight = pNewLR;<br />pNewR->pLeft = pNewRL;<br />pNewR->pRight = pNewRR;</p><p>return pRoot;<br />}<br />void main()<br />{<br />bstNode* pRoot = buildupTree();<br />std::cout<<medianInBST(pRoot)<<std::endl;<br />system("pause");<br />}

說實話這樣的題目還是比較喜歡的,考到了很多的概念和想法,

a.中序遍曆

b.BST轉化成DLL

c.尋找鏈表的中間節點

如果任何一個問題割裂開了問, 都是比較容易解決的。困難就在於如何用已知的辦法組合地解決未知的問題,發人深思,餘是以記之。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.