樹狀顯示二叉樹

來源:互聯網
上載者:User

二叉樹一個重要的資料結構,如何方便直觀的顯示一棵樹對於學習非常重要。

 

現設計了如下演算法:

      編寫函數displaytree(二叉樹的根指標,資料值寬度,螢幕的寬度)輸出樹的直觀。輸出的二叉樹是垂直列印的,同層的節點在同一行上。

問題描述:
假設資料寬度datawidth=2,而螢幕寬度screenwidth為64=2^6,假設節點的輸出位置用(層號,須列印的空格數)來界定。
第0層:根在(0,32)處輸出;
第1層:因為根節點縮排了32個空格,所以下一層的位移量(offset)為32/2 = 16 = screenwidth/2^2。即第一層的兩個節點的位置(1,32-offset),(1,32+offset) 即(1,16),(1,48)。
第2層:第二層的位移量offset為screenwidth/23。第二層的四個節點的位置分別是(2,16-offset),(2,16+offset),(2,48-offset),(2,48+offset)即(2,8),(2,24),(2,40),(2,56)。……
第i層: 第i層的位移量offset為screenwidth/2i+1。第i層的每個節點的位置是訪問第i-1層其雙親節點時確定的。假設其雙親的位置為(i- 1,parentpos)。若其第i層的節點是其左孩子,那末左孩子的位置是(i,parentpos-offset),右孩子的位置是(i,parentpos+offset)。

利用二叉樹的層次遍曆演算法實現。利用兩個隊列Q,QI。

隊列Q中存放節點資訊。

隊列QI中存相應於隊列Q中的節點的位置資訊,包括層號、位置,是否換行、需要列印的空格數。

當節點被加入到Q時,根據前一個節點的資訊來計算當期的列印資訊,並且將相應的列印資訊被存到QI中。

 

class Node<br />{<br />public:<br />int key;<br />Node *left;<br />Node *right;<br />Node *parent;<br />Node(){};<br />Node(int key){this->key=key;left=right=parent=NULL;}<br />};<br />class DisplayInfo<br />{<br />public:<br />int level;<br />int pos; //結點在螢幕中的絕對位置<br />bool enter;<br />int spaceNum;<br />};<br />class BST<br />{<br />public:<br />Node *root;<br />BST(){root=NULL;}<br />void insert(int key);<br />void BFSDisplayTree(void);<br />void NatureDisplayTree(void);<br />};

程式如下:

void BST::NatureDisplayTree()<br />{<br />int i;<br /> list<Node *>Q;<br /> list<DisplayInfo>QI;<br /> int screenWidth=64;<br /> int dataWidth=2;<br /> DisplayInfo info; //將插入隊列的結點的列印資訊<br /> DisplayInfo preInfo; //隊尾的結點的列印資訊<br /> Node *curNode; //隊列當前取出的結點<br /> DisplayInfo curInfo; //隊列當前取出的結點的列印資訊<br /> if(!root)<br /> {<br /> printf("Tree is empty !/n");<br /> return;<br /> }<br /> printf("Nature Display Tree:/n");<br /> Q.push_back(root);<br /> info.level=1;<br /> info.enter=true;<br /> info.spaceNum=screenWidth>>info.level;<br /> info.pos=info.spaceNum;<br /> QI.push_back(info);<br /> preInfo=info;<br /> while(Q.size())<br /> {<br /> curNode=Q.front();<br /> Q.pop_front();<br /> curInfo=QI.front();<br /> if(curInfo.enter)<br /> printf("/n/n");<br /> for (i=0;i<curInfo.spaceNum;i++)<br />printf(" ");<br /> printf("%2d",curNode->key);<br /> QI.pop_front();<br /> if(curNode->left)<br /> {<br /> Q.push_back(curNode->left);<br /> info.level=curInfo.level+1;<br /> info.pos=curInfo.pos-(screenWidth>>info.level);<br /> if(info.level>preInfo.level)<br /> {<br /> info.enter=true;<br /> info.spaceNum=info.pos;<br /> }<br /> else<br /> {<br /> info.enter=false;<br /> info.spaceNum=info.pos-preInfo.pos;<br /> }<br /> info.spaceNum-=dataWidth;<br /> QI.push_back(info);<br /> preInfo=info;</p><p> }<br /> if(curNode->right)<br /> {<br /> Q.push_back(curNode->right);<br /> info.level=curInfo.level+1;<br /> info.pos=curInfo.pos+(screenWidth>>info.level);<br /> if(info.level>preInfo.level)<br /> {<br /> info.enter=true;<br /> info.spaceNum=info.pos;<br /> }<br /> else<br /> {<br /> info.enter=false;<br /> info.spaceNum=info.pos-preInfo.pos;<br /> }<br /> info.spaceNum-=dataWidth;<br /> QI.push_back(info);<br /> preInfo=info;<br /> }</p><p> }<br /> printf("/n");<br />} 

需要注意的是:如果將插入的結點和隊尾的結點的level不同,說明需要換行

採用隊列的方式是為了實現廣度優先遍曆:從根結點開始,一層一層的將結點加入到隊列中。

遍曆的過程也是顯示的過程

結果如下

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.