二叉樹是一個比較重要的數據結構,這篇文章將基於linux下實現BinaryTree
一.進入工作目錄,我自己在工作目錄下建了一個DataStruct的目錄。
$touch BinaryTree.cpp 的文件
$vim BinaryTree.cpp
二.二叉樹
1).二叉樹的建立 -- 遞歸建立
需要注意的點
a.index爲數組下標索引,因爲是遞歸建立,所以必須傳引用。
b.invaild爲無效數值,可以終止數的向下生長。
2).二叉樹的先序遍歷
a.先序遍歷根節點,再遍歷左子樹,後遍歷右子樹。
3).二叉樹的中序遍歷
a.先序遍歷左子樹,再遍歷根節點,後遍歷右子樹。
4).二叉樹的後序遍歷
a.先序遍歷左子樹,再遍歷右子樹,後遍歷根節點。
5).二叉樹的層序遍歷
a.借用隊列先進先出的特性,先壓根節點,之後訪問根節點,pop根節點,壓入左右子數,以此訪問。
三.測試用例
$g++ -o BinaryTree BinaryTree.cpp -g (-g 是加入調試信息,方便gdb調試)
$./BinaryTree
結果
附件:
代碼:
#pragma once #include<iostream> using namespace std; #include<queue> template<class T> struct BinaryTreeNode { BinaryTreeNode(const T& x) :_data(x) , _left(NULL) , _right(NULL) {} T _data; BinaryTreeNode<T>* _left; BinaryTreeNode<T>* _right; }; template<class T> class BinaryTree { typedef BinaryTreeNode<T> Node; public: BinaryTree() :_root(NULL) {} BinaryTree(const T* a, size_t size, const T& invaild) { size_t index = 0; _root = _BinaryTree(a, size, index, invaild); } ~BinaryTree() {} BinaryTree(const BinaryTree<T>& t) { _root = _Copy(t._root); } void prevOrder() //前序遍歷 { _prevOrder(_root); cout << endl; } void inOrder() //中序遍歷 { _inOrder(_root); cout << endl; } void nextOrder() //後序遍歷 { _nextOrder(_root); cout << endl; } void levelOrder() { _levelOrder(_root); } size_t size() { return _size(_root); } size_t Depth() { return _Depth(_root); } size_t leafsize() { return _leafsize(_root); } size_t GetKLevel(int k) { return _GetKLevel(int k); } protected: void _Destroy(Node* root) { if (root == NULL) { return; } //-------------------------------------------------- _Destroy(root->_left); _Destroy(root->_right); _Destroy root; } Node* _Copy(Node* root) { if (root == NULL) { return NULL; } Node* newRoot = new Node(root->_data); newRoot->_left = _Copy(root->_left); newRoot->_right = _Copy(root->_right); return newRoot; } Node* _BinaryTree(const T* a, size_t size, size_t& index, const T& invaild) //必須要給index加引用 { Node* root = NULL; if (index < size && a[index] != invaild) { root = new Node(a[index]); root->_left = _BinaryTree(a, size, ++index, invaild); root->_right = _BinaryTree(a, size, ++index, invaild); } return root; } void _prevOrder(Node* root) { //Node* cur = root; if (root == NULL) { return; } cout << root->_data << " "; _prevOrder(root->_left); _prevOrder(root->_right); } void _inOrder(Node* root) { if (root == NULL) { return; } _inOrder(root->_left); cout << root->_data << " "; _inOrder(root->_right); } void _nextOrder(Node* root) { if (root == NULL) { return; } _nextOrder(root->_left); _nextOrder(root->_right); cout << root->_data << " "; } size_t _size(Node* root) { if (root == NULL) { return 0; } //左子樹加上右子樹加上根節點 return _size(root->_left) + _size(root->_right) + 1; } //size_t _Depth(Node* root) //{ // if (root == NULL) // { // return 0; // } // return _Depth(root->_left) > _Depth(root->_right) ? _Depth(root->_left)+1 : _Depth(root->_right)+1; //效率太低 //} size_t _Depth(Node* root) { if (root == NULL) { return 0; } int leftdepth = _Depth(root->_left); //--------------------------------- int rightdepth = _Depth(root->_right); return leftdepth > rightdepth ? leftdepth+1 : rightdepth+1; } size_t _leafsize(Node* root) { static size_t size = 0; if (root == NULL) { return 0; } if (root->_left == NULL && root->_right == NULL) { ++size; return size; } _leafsize(root->_left); _leafsize(root->_right); return size; } size_t _GetKLevel(int k) { if (_root == NULL) { return 0; } if (k == 1) { return 1; } Node* cur = _root; static size_t LeafKSize = 0; static size_t Level = 1; if (Level == k - 1) { if (_root->_left != NULL) { leafsize++; } if (_root->_right != NULL) { leafsize++; } } Level++; _GetKLevel(_root->_left); _GetKLevel(_root->_right); } void _levelOrder(Node* root) { if (root == NULL) { return; } queue<Node*> qTree; qTree.push(root); while (!qTree.empty()) { Node* cur = qTree.front(); qTree.pop(); cout << cur->_data << " "; if (cur->_left) { qTree.push(cur->_left); } if (cur->_right) { qTree.push(cur->_right); } } cout << endl; } protected: Node* _root; };
以上就是本人在學習過程中的一些經驗總結。當然,本人能力有限,難免會有紕漏,希望大家可以指正。