數據結構之二叉樹的構建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;
}

結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章