標籤:com return 最大 中間 其他 sem std 序號 遞增
二叉樹的構建要注意與鏈式表的區別,二叉樹這裡的構建十分低級,每個樹只是構建了一個單一的二叉樹節點,總體來看是有下向上構建的。使用者需要手動去構建自己需要的樹,而不是直接去插入資料就到二叉樹中了,因為不是鏈式結構的單一,二叉樹十分豐富的。
提一下遍曆:
迭代的方式遍曆十分簡單。先序、中序、後序遍曆都只是針對根節點。比如中序,就是先遍曆左子樹-->根節點-->右子樹。(根節點在中間)
/*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(){ delete _root;}template<class T>void JBBinaryTree<T>::clear() { 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;//將右子樹單獨拆成一棵樹 delete _root; 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;}
結果:
資料結構之二叉樹的構建C++版