數據結構之二叉樹的構建C++版


二叉樹的構建要注意與鏈式表的區別,二叉樹這里的構建十分低級,每個樹只是構建了一個單一的二叉樹節點,總體來看是有下向上構建的。用戶需要手動去構建自己需要的樹,而不是直接去插入數據就到二叉樹中了,因為不是鏈式結構的單一,二叉樹十分豐富的。

提一下遍歷:

迭代的方式遍歷十分簡單。先序、中序、后序遍歷都只是針對根節點。比如中序,就是先遍歷左子樹-->根節點-->右子樹。(根節點在中間)

/*
1) 樹的基本概念:
    度:說白了就是節點擁有的子分支數
    葉子節點:說白了就是度為0的節點
    雙親:說白了就是父親節點
    層次:約定根節點為1,以后的子節點依次遞增
    高度:說白了就是層次最大的數
2)二叉樹的類型
    1>滿二叉樹:葉子必須位於最后一層,並且其他節點度為2
    2>擴充二叉樹:除葉子節點外,其他節點度為2
        1,擴充二叉樹的最大特點在於他的外路徑長度=內路徑的長度+2*非葉節點的數目
        2,典型應用就是哈弗曼編碼
    3>完全二叉樹: 只有最后兩層的節點的度能小於2,並且最后1層的葉子節點必須靠左邊。
        1,將整個完全二叉樹依照從左到右,從上到下的進行0-->n進行編號,若子節點序號為i,則父節點為(i-1)/2。
        2,典型的應用大小堆的實現。
    4>其他類型二叉樹
3)森林與二叉樹的互轉
*/

template <class T>
struct  BTNode
{
    BTNode<T> *_lChild, *_rChild;
    T element;
    BTNode(const T &e) {
        element = e;
        _lChild = _rChild = NULL;
    }
};
template <class T>
class JBBinaryTree
{    
public:    
    JBBinaryTree();
    ~JBBinaryTree();
    BTNode<T> *_root;
    //清空當前樹
    void clear();
    //獲取到當前元素
    T getElement()    const;
    //判斷當前二叉樹是不是空二叉樹
    bool isEmpty()    const;
    //構建一棵數
    void makeTree(const T &x,JBBinaryTree<T> *left,JBBinaryTree<T> *right);
    //拆除一棵數
    void breakTree(T &x,JBBinaryTree*left,JBBinaryTree*right);
    //前序遍歷 統一采用遞歸遍歷
    void preOrder(BTNode<T> *t);
    //中序遍歷
    void inOrder(BTNode<T> *t);
    //后序遍歷
    void postOrder(BTNode<T> *t);
};

template <class T>
JBBinaryTree<T>::JBBinaryTree()
{
    _root = NULL;
}

template<class T>
JBBinaryTree<T>::~JBBinaryTree()
{
    clear();
}

template<class T>
void JBBinaryTree<T>::clear() {
  if(_root==NULL){
    return;
  }
  delete _root; _root = NULL; } template<class T> T JBBinaryTree<T>::getElement() const { if (isEmpty()) { reurn NULL; } return _root->element; } template<class T> bool JBBinaryTree<T>::isEmpty() const { return _root == NULL; } template<class T> void JBBinaryTree<T>::makeTree(const T &x, JBBinaryTree<T> *left, JBBinaryTree<T> *right) { if (_root)return;//如果根節點不為空 就直接return 這實際上讓用戶操作起來十分不方便 不能自己構建自己 必須重一個節點 _root = new BTNode<T>(x);//實例化二叉樹根節點 _root->_lChild = left->_root;//讓左指針指向左子樹的根節點 _root->_rChild = right->_root;//讓右指針指向右子樹的根節點 left->_root = right->_root = NULL; } template<class T> void JBBinaryTree<T>::breakTree(T &x, JBBinaryTree*left, JBBinaryTree*right) { if (!_root || left == right || left->_root || right->_root) { //若此樹本身就是空的,或則用於承接的左右樹本身一樣,或則用於承接的左子樹不為空都直接退出 return; } x = _root->element;//將這個樹的根節點的元素域轉移走 left->_root = _root->_lChild;//將左子樹單獨拆成一棵樹 right->_root = _root->_rChild;//將右子樹單獨拆成一棵樹 clear(); } template<class T> void JBBinaryTree<T>::preOrder(BTNode<T> *t) { if (t) { printf("%d",t->element); preOrder(t->_lChild); preOrder(t->_rChild); } } template<class T> void JBBinaryTree<T>::inOrder(BTNode<T> *t) { if (t) { inOrder(t->_lChild); printf("%d",t->element); inOrder(t->_rChild); } } template<class T> void JBBinaryTree<T>::postOrder(BTNode<T> *t) { if (t) { postOrder(t->_lChild); postOrder(t->_rChild); printf("%d",t->element); } }

下面看一下主程序

  

#include "stdafx.h"
#include"stdlib.h"
#include"JBQueue.h"
#include"JBStack.h"
#include"JBBinaryTree.h"

int main()
{
    {
        JBBinaryTree<int> L,R,a,b,c,d,e;
        a.makeTree(0,&L,&R);
        b.makeTree(1,&L,&R);
        c.makeTree(2,&a,&b);
        d.makeTree(3,&a,&b);
        e.makeTree(4,&c,&d);
        printf("前序遍歷:");
        e.preOrder(e._root);
        printf("\n中序遍歷:");
        e.inOrder(e._root);
        printf("\n后序遍歷:");
        e.postOrder(e._root);
        printf("\n");
    }
    system("pause");
    return 0;
}

結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM