在二元樹的應用中, 常見的有二元排序樹, 二元搜尋樹, 引線二元樹等, 這裡將會針對二元排序樹進行介紹.
二元排序樹 :
事實上, 二元樹是一種很好的排序應用模式, 因為在建立二元樹的同時, 資料已經經過初步的比較判斷, 並依照二元樹的建立規則來存放資料. 規則如下 :
從上面的規則我們知道, 左子樹的值一定小於樹根, 而右子樹的值一定大於樹根. 因此只要利用 “中序走訪” 方式就可以得到由小到大排序好的資料, 如果是想求由大到小排列, 可將最後結果至於堆疊再使用堆疊pop 出來. 以下是簡單的示範 :
根據上面範例建立完的二元樹後, 經由中序走訪可得 16, 25, 27, 32, 35 並按照由小到大排列. 因為在輸入資料的同時就開始建立二元樹, 所以在完成資料輸入並建立完二元樹後, 經由中序走訪便可以很輕鬆的完成排序.
範例代碼 :
* LSBinaryTree.h 代碼 :
- #include
- using namespace std;
- class LSBinaryTreeNode{
- public:
- int data;
- class LSBinaryTreeNode *left;
- class LSBinaryTreeNode *right;
- LSBinaryTreeNode(){
- data = -1;
- left = NULL;
- right = NULL;
- }
- };
- typedef class LSBinaryTreeNode lsbtNode;
- typedef lsbtNode *lsbtNodePoint;
- class LSBinaryTree{
- lsbtNodePoint rootNode;
- public:
- LSBinaryTree(){
- rootNode = NULL;
- }
- virtual void add_Node_To_Tree(int value);
- virtual int getLevel(); /*獲取此二元樹的Level/階度*/
- virtual int getNodeCount(); /*獲取此二元樹的設定節點個數*/
- virtual void inorder(); /*中序走訪二元樹*/
- virtual void preorder(); /*前序走訪二元樹*/
- virtual void postorder(); /*後序走訪二元樹*/
- protected:
- virtual void _inorder(lsbtNodePoint p);
- virtual void _preorder(lsbtNodePoint p);
- virtual void _postorder(lsbtNodePoint p);
- virtual int _getNodeCount(lsbtNodePoint p);
- virtual int _getDepth(lsbtNodePoint p);
- };
- #include "LSBinaryTree.h"
- void LSBinaryTree::add_Node_To_Tree(int value) {
- lsbtNodePoint currentNode;
- lsbtNodePoint newnode;
- int flag=0; // 用來紀錄是否插入新的節點
- newnode = (lsbtNodePoint)malloc(sizeof(lsbtNode));
- newnode->data = value;
- newnode->left = NULL;
- newnode->right = NULL;
- if(this->rootNode == NULL){
- rootNode = newnode;
- } else {
- currentNode = this->rootNode;
- while(!flag) {
- if(value<=currentNode->data) { // 往左子樹
- if(currentNode->left == NULL) {
- currentNode->left = newnode;
- flag = 1;
- } else {
- currentNode = currentNode->left;
- }
- } else { // 往右子樹
- if(currentNode->right == NULL){
- currentNode->right = newnode;
- flag = 1;
- } else {
- currentNode = currentNode->right;
- }
- }
- }
- }
- }
- int LSBinaryTree::getLevel() {
- return _getDepth(this->rootNode);
- }
- int LSBinaryTree::getNodeCount() {
- return _getNodeCount(this->rootNode);
- }
- int LSBinaryTree::_getNodeCount(lsbtNodePoint p){
- if(p!=NULL) {
- return this->_getNodeCount(p->left) + this->_getNodeCount(p->right) + 1;
- } else {
- return 0;
- }
- }
- int LSBinaryTree::_getDepth(lsbtNodePoint p){
- if(p!=NULL) {
- int ld = 1+ this->_getDepth(p->left);
- int rd = 1+ this->_getDepth(p->right);
- if(ld>rd) {
- return ld;
- } else {
- return rd;
- }
- } else {
- return 0;
- }
- }
- void LSBinaryTree::inorder() {
- this->_inorder(this->rootNode);
- }
- void LSBinaryTree::_inorder(lsbtNodePoint p){
- if(p != NULL) {
- if(p->left != NULL)
- this->_inorder(p->left);
- cout << "[" << p->data << "] ";
- if(p->right != NULL)
- this->_inorder(p->right);
- }
- }
- void LSBinaryTree::preorder() {
- this->_preorder(this->rootNode);
- }
- void LSBinaryTree::_preorder(lsbtNodePoint p) {
- if(p!=NULL) {
- cout << "[" << p->data << "] ";
- if(p->left!=NULL)
- _preorder(p->left);
- if(p->right!=NULL)
- _preorder(p->right);
- }
- }
- void LSBinaryTree::postorder() {
- this->_postorder(this->rootNode);
- }
- void LSBinaryTree::_postorder(lsbtNodePoint p){
- if(p!=NULL){
- if(p->left!=NULL)
- _postorder(p->left);
- if(p->right!=NULL)
- _postorder(p->right);
- cout << "[" << p->data << "] ";
- }
- }
- void ch06_05(bool b) {
- if(b) {
- int value=0;
- LSBinaryTree btree;
- while(true) {
- cout << "請輸入節點值(輸入-1離開): ";
- cin >> value;
- if(value == -1)
- break;
- else
- btree.add_Node_To_Tree(value);
- }
- cout << "中序走訪: ";
- btree.inorder();
- cout << endl;
- }
- }
執行結果 :
補充說明 :
* [ 資料結構 小學堂 ] 樹狀結構導論 : 二元樹的走訪
沒有留言:
張貼留言